jskelet 0.6.0 → 0.6.2
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/AGENTS.md +2 -3
- package/CHANGELOG.md +158 -103
- package/README.md +7 -14
- package/bin/jskelet.mjs +1 -1
- package/docs/02-mimari.md +6 -1
- package/docs/03-routing.md +3 -1
- package/docs/04-render-ve-sablonlar.md +25 -0
- package/docs/06-cache.md +18 -7
- package/docs/07-yapilandirma.md +29 -9
- package/docs/09-dev-araclari.md +17 -7
- package/docs/10-dagitim.md +8 -12
- package/docs/README.md +3 -28
- package/docs/en/02-architecture.md +7 -1
- package/docs/en/03-routing.md +3 -1
- package/docs/en/04-rendering.md +24 -0
- package/docs/en/06-caching.md +21 -7
- package/docs/en/07-configuration.md +29 -9
- package/docs/en/09-dev-tools.md +18 -7
- package/docs/en/10-deployment.md +8 -13
- package/docs/en/README.md +3 -30
- package/package.json +2 -2
- package/src/config/defaults.js +36 -3
- package/src/config/index.js +137 -26
- package/src/server/create-app.js +9 -0
- package/src/server/html-cache.js +178 -32
- package/src/server/middleware/dev-gate.js +21 -8
- package/src/server/middleware/robots-txt.js +341 -0
- package/src/server/prewarm.js +137 -51
- package/src/server/render.js +3 -1
- package/types/config/defaults.d.ts +31 -3
- package/types/config/index.d.ts +5 -0
- package/types/server/html-cache.d.ts +40 -6
- package/types/server/middleware/robots-txt.d.ts +33 -0
- package/types/server/prewarm.d.ts +6 -3
package/AGENTS.md
CHANGED
|
@@ -29,8 +29,7 @@ zaten tartışılmış:
|
|
|
29
29
|
|
|
30
30
|
Belgeler iki dilde: Türkçesi `docs/`, İngilizcesi `docs/en/` altında ve
|
|
31
31
|
dosyalar birebir eşlenik. Bir belgeyi değiştirdiysen karşılığını da güncelle;
|
|
32
|
-
|
|
33
|
-
servis ettiği için eksik kalan çeviri kullanıcıya görünür.
|
|
32
|
+
eksik kalan çeviri kullanıcıya görünür.
|
|
34
33
|
|
|
35
34
|
## Doğrulama
|
|
36
35
|
|
|
@@ -123,7 +122,7 @@ sessizce çıktıdan düşer.
|
|
|
123
122
|
|
|
124
123
|
Framework'ün genel yüzeyini değiştirdiysen (`route()` imzası, hook adları,
|
|
125
124
|
config alanları, client API'si) `examples/minimal`, `examples/blog` ve
|
|
126
|
-
`examples/
|
|
125
|
+
`examples/dashboard`'i de güncelle. Örnekler belgelerdeki kod parçalarının kaynağı; kaymaları en hızlı
|
|
127
126
|
fark edilen yer orası.
|
|
128
127
|
|
|
129
128
|
## Windows notları
|
package/CHANGELOG.md
CHANGED
|
@@ -10,121 +10,175 @@ one is listed under a **Breaking** heading.
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
-
- `
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- Published TypeScript declaration files under `types/` for `jskelet`,
|
|
32
|
-
`jskelet/client`, `jskelet/html`, `jskelet/tags`, `jskelet/cookies` and
|
|
33
|
-
`jskelet/log` (`npm run types`).
|
|
34
|
-
- Client build accepts `.ts` / `.mts` entries and islands (esbuild); manifest
|
|
35
|
-
keys stay `*.js`. Conflicting stems (`main.js` + `main.ts`) fail the build.
|
|
36
|
-
Icon usage scan includes `.ts` / `.mts`.
|
|
37
|
-
|
|
38
|
-
- Local flat `icons/` directory as the exclusive SVG sprite source when present
|
|
39
|
-
(`icons.dir`, default `"icons"`): `house.svg` / `house-bold.svg` file names,
|
|
40
|
-
XOR with `@phosphor-icons/core` (Phosphor only when the directory is absent).
|
|
41
|
-
The hashed sprite still lands under `public/assets/` and is precompressed.
|
|
42
|
-
- Auth handoff hardening: `allowedCookieNames` allowlist, pending-ticket and
|
|
43
|
-
per-IP mint limits, and RFC 6265 cookie-name validation on `serializeCookie`
|
|
44
|
-
(`isValidCookieName`).
|
|
13
|
+
- `robots.txt` responses gain a trailing JSkelet note that disallows framework
|
|
14
|
+
endpoints (`/_jskelet/`, `/__jskelet/`, `/_fragment/`, plus a custom admin,
|
|
15
|
+
image, handoff, or dev path when it sits outside those prefixes). Every
|
|
16
|
+
user-agent already named in the file is repeated in that block, so a
|
|
17
|
+
crawler-specific group still sees the rules.
|
|
18
|
+
|
|
19
|
+
### Breaking
|
|
20
|
+
|
|
21
|
+
- Dev gate is opt-in
|
|
22
|
+
`DEV_TOKEN` in the environment no longer locks the site. Require the token
|
|
23
|
+
only with `devGate: true` or `DEV_GATE=1`. `DEV_GATE=0` turns the gate off
|
|
24
|
+
even when config enabled it.
|
|
25
|
+
- Cache ceilings
|
|
26
|
+
`cache().maxEntries` above 800, `cache().data.maxEntries` above 20,000, and
|
|
27
|
+
`prewarm.onVisit` above `perPage` 20, `rps` 2, or `concurrency` 2 are clamped
|
|
28
|
+
at load with a warning. `onVisit` `rps: 0` is no longer unlimited. The HTML
|
|
29
|
+
cache also stops growing past 256 MB of stored HTML plus compressed bodies;
|
|
30
|
+
a single page larger than that is not stored.
|
|
45
31
|
|
|
46
32
|
### Fixed
|
|
47
33
|
|
|
48
|
-
-
|
|
34
|
+
- Visit warming skips pages that are already fresh when the cache key has a
|
|
35
|
+
vary prefix or a trailing `?`. With `vary.host`, warm requests stay on
|
|
36
|
+
loopback and send the public host as `x-forwarded-host`, so a second
|
|
37
|
+
`127.0.0.1` HTML entry is not created. The onVisit queue holds at most 64
|
|
38
|
+
paths.
|
|
39
|
+
|
|
40
|
+
### Removed
|
|
41
|
+
|
|
42
|
+
- `examples/marketing` — the marketing site now lives as a standalone app
|
|
43
|
+
outside this repository (`jskelet-marketing`).
|
|
44
|
+
|
|
45
|
+
## [0.6.0] - 2026-09-21
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Port reclaim with `--murder`
|
|
50
|
+
`jskelet dev --murder` and `jskelet start --murder` kill whatever already
|
|
51
|
+
holds the listen port and bind in its place. Without the flag the CLI still
|
|
52
|
+
refuses to start, but now with a clear error (pid + hint) instead of a bare
|
|
53
|
+
`EADDRINUSE`.
|
|
54
|
+
- Layout built-ins for `.jsk`
|
|
55
|
+
`<Stylesheets />`, `<BodyScripts />`, and `<JsonLd />` emit the asset /
|
|
56
|
+
script / JSON-LD loops from layout without calling helpers in the expression
|
|
57
|
+
language.
|
|
58
|
+
- Framework default layout as `.jsk`
|
|
59
|
+
Ships as `src/templates/layout.jsk` with a checked-in `layout.render.js`
|
|
60
|
+
(`node scripts/compile-framework-layout.mjs`, `--check` for drift).
|
|
61
|
+
`jskelet/layout` points at the `.jsk` source; the legacy EJS copy remains at
|
|
62
|
+
`jskelet/layout/ejs`.
|
|
63
|
+
- JSK editor tooling
|
|
64
|
+
The VS Code / Cursor JSK extension (v0.2.0) reports diagnostics in Problems
|
|
65
|
+
on open/save and offers PascalCase component completions from
|
|
66
|
+
`views/components`.
|
|
67
|
+
- `<!DOCTYPE>` parsing in `.jsk`
|
|
68
|
+
Doctype and other `<!…>` declarations parse correctly instead of hanging the
|
|
69
|
+
template compiler.
|
|
70
|
+
- `jskelet migrate` for Next.js App Router
|
|
71
|
+
Codemod with `scan` inventory, `apply` (JSX pages → controller + `.jsk`,
|
|
72
|
+
presentational components → HTML string helpers, `"use client"` → island
|
|
73
|
+
stubs), and `config` draft from `next.config`. Ships with `@babel/parser` /
|
|
74
|
+
`@babel/types`.
|
|
75
|
+
- Published TypeScript declarations
|
|
76
|
+
`.d.ts` files under `types/` for `jskelet`, `jskelet/client`, `jskelet/html`,
|
|
77
|
+
`jskelet/tags`, `jskelet/cookies`, and `jskelet/log` (`npm run types`).
|
|
78
|
+
- TypeScript client entries and islands
|
|
79
|
+
The client build accepts `.ts` / `.mts` entries and islands via esbuild;
|
|
80
|
+
manifest keys stay `*.js`. Conflicting stems (`main.js` + `main.ts`) fail the
|
|
81
|
+
build. Icon usage scan includes `.ts` / `.mts`.
|
|
82
|
+
- Local `icons/` sprite source
|
|
83
|
+
When a flat `icons/` directory is present (`icons.dir`, default `"icons"`),
|
|
84
|
+
it is the exclusive SVG sprite source (`house.svg` / `house-bold.svg`).
|
|
85
|
+
Phosphor is used only when that directory is absent. The hashed sprite still
|
|
86
|
+
lands under `public/assets/` and is precompressed.
|
|
87
|
+
- Auth handoff hardening
|
|
88
|
+
`allowedCookieNames` allowlist, pending-ticket and per-IP mint limits, plus
|
|
89
|
+
RFC 6265 cookie-name validation on `serializeCookie` (`isValidCookieName`).
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- Clearer `jskelet dev` startup failures
|
|
94
|
+
The CLI prints the real server failure (for example port already in use /
|
|
49
95
|
`--murder` hint) instead of only `server exited (code 1)` when the child
|
|
50
96
|
dies during startup.
|
|
51
|
-
- Marketing
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
resolution (open-redirect SSRF).
|
|
97
|
+
- Marketing trust-bar icons after `.jsk` migration
|
|
98
|
+
`icons.scan` now covers `routes/`, so names declared in controllers
|
|
99
|
+
(`Package`, `TextT`, `ShieldCheck`, …) land in the sprite again.
|
|
100
|
+
- Open Graph routes with a `.png` suffix
|
|
101
|
+
Paths like `/og/…/:slug.png` escape the dot for Express 5 / path-to-regexp,
|
|
102
|
+
so the handler matches instead of falling through to the HTML 404.
|
|
103
|
+
- Safer remote image optimizer redirects
|
|
104
|
+
Redirects are no longer followed blindly; each hop is re-checked against
|
|
105
|
+
`allowHosts`, blocked private addresses, and DNS resolution (open-redirect
|
|
106
|
+
SSRF).
|
|
62
107
|
|
|
63
108
|
### Breaking
|
|
64
109
|
|
|
65
|
-
- `ejs` is an optional peer
|
|
66
|
-
install it; apps that still have `.ejs`
|
|
67
|
-
`npm i ejs`. Missing EJS when an `.ejs` file is
|
|
68
|
-
install/migrate hint.
|
|
69
|
-
-
|
|
110
|
+
- `ejs` is an optional peer
|
|
111
|
+
Apps that only use `.jsk` need not install it; apps that still have `.ejs`
|
|
112
|
+
views or layouts must `npm i ejs`. Missing EJS when an `.ejs` file is
|
|
113
|
+
rendered throws a clear install/migrate hint.
|
|
114
|
+
- Default layout export is `.jsk`
|
|
115
|
+
`jskelet/layout` now resolves to `layout.jsk` (was `layout.ejs`). Use
|
|
70
116
|
`jskelet/layout/ejs` for the legacy file.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- Secret-like `clientEnv`
|
|
117
|
+
- Auth handoff requires cookie allowlist
|
|
118
|
+
`auth.crossSubdomainHandoff` mint needs a non-empty `allowedCookieNames`
|
|
119
|
+
list; `true` alone no longer accepts arbitrary cookie names.
|
|
120
|
+
- Production builds omit client sourcemaps
|
|
121
|
+
Development still emits them; production client bundles do not.
|
|
122
|
+
- Secret-like `clientEnv` keys fail the build
|
|
123
|
+
Names that look like secrets are rejected instead of being inlined into the
|
|
124
|
+
client bundle.
|
|
77
125
|
|
|
78
126
|
### Changed
|
|
79
127
|
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
128
|
+
- Marketing changelog as release notes
|
|
129
|
+
`/changelog` hides Unreleased, lists every published release without
|
|
130
|
+
pagination, and shows each note as a titled card with a short headline plus
|
|
131
|
+
a longer explanation (Keep-a-Changelog sections: Added / Changed / Fixed /
|
|
132
|
+
…).
|
|
133
|
+
- Examples are `.jsk` only
|
|
134
|
+
`minimal`, `blog`, `dashboard`, and `marketing` use `.jsk` for layouts,
|
|
135
|
+
pages, and partials; EJS files were removed from those trees.
|
|
136
|
+
- Stricter, clearer template compiler
|
|
137
|
+
Unknown PascalCase components fail the build. Errors for forbidden function
|
|
138
|
+
calls, unknown includes (with location), and unclosed `{#if}` / `{#each}` at
|
|
139
|
+
EOF are clearer; icon scan recognizes `<Icon name="…" />`.
|
|
140
|
+
- Docs present `.jsk` as the default
|
|
141
|
+
Docs / AGENTS / README tell the build-time `.jsk` story first; EJS is
|
|
142
|
+
documented as an optional legacy peer.
|
|
143
|
+
- Standalone JSK VSIX packaging
|
|
144
|
+
The VS Code / Cursor extension (`extensions/vscode-jsk`) uses the new 3D
|
|
145
|
+
`.jsk` mark as marketplace and explorer icon, and packages as a standalone
|
|
146
|
+
VSIX (vendors `src/compile`) for Marketplace publish.
|
|
147
|
+
- Migrate peers are optional
|
|
148
|
+
`@babel/parser` and `@babel/types` are optional peers used only by migrate.
|
|
149
|
+
They are no longer installed with every `jskelet` install; missing peers
|
|
150
|
+
throw an install hint. Unused `@babel/traverse` was dropped.
|
|
151
|
+
- Auth handoff sits after CSRF
|
|
152
|
+
Mint mounts after CSRF so origin checks apply to
|
|
98
153
|
`POST /_jskelet/auth/handoff`.
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
page
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
lit panels.
|
|
154
|
+
- Stronger security docs
|
|
155
|
+
Docs (TR/EN) expand `trustProxy` / `csrf.token` guidance and include a
|
|
156
|
+
fuller security-headers example under `headers()`.
|
|
157
|
+
- Marketing copy defaults to `.jsk`
|
|
158
|
+
EN/TR marketing and how-it-works examples present `.jsk` as the default
|
|
159
|
+
template surface; the compare column for hand-written Express + EJS stays as
|
|
160
|
+
a competitor. Scaffold and migrate mappings name `.jsk` pages and layouts.
|
|
161
|
+
- New geometric brand mark
|
|
162
|
+
Framework and marketing logos live at `src/logo.png` (admin / devtools) and
|
|
163
|
+
`examples/marketing/public/logo.png`. Marketing serves local favicons via
|
|
164
|
+
metadata `extraTags`.
|
|
165
|
+
- Development 5xx diagnostics
|
|
166
|
+
In `NODE_ENV=development`, 5xx responses show the error message and stack
|
|
167
|
+
instead of the polished 500 page / `hooks.error()`. Production still returns
|
|
168
|
+
the minimal status page with no internals.
|
|
169
|
+
- Marketing fit copy for signed-in panels
|
|
170
|
+
EN/TR fit copy treats dashboards and per-visitor panels as a supported path
|
|
171
|
+
(`private: true`, fragments). The poor-fit column names SPA shells,
|
|
172
|
+
collaborative client trees, streaming/RSC, and built-in real-time transport.
|
|
173
|
+
- Marketing copy for 0.5.x surfaces
|
|
174
|
+
EN/TR copy reflects host `vary`, early refresh, classic vs `onVisit`
|
|
175
|
+
prewarm, local `icons/`, shared cookies, and `opengraph-image` → `ogHandler`
|
|
176
|
+
on the migrate table. Pages serve per-locale OG cards at
|
|
177
|
+
`/og/:locale/:page.png`.
|
|
178
|
+
- Marketing visual language
|
|
179
|
+
Dark cyan glass look with shared `glass-panel` surfaces, numbered lit feature
|
|
180
|
+
cards, a 3D stack illustration on the home hero, and rotating cyan border
|
|
181
|
+
beams on lit panels.
|
|
128
182
|
|
|
129
183
|
## [0.5.4] - 2026-09-18
|
|
130
184
|
|
|
@@ -503,7 +557,8 @@ Initial release.
|
|
|
503
557
|
- Documentation under `docs/` and three examples: `minimal`, `blog`,
|
|
504
558
|
`marketing`.
|
|
505
559
|
|
|
506
|
-
[Unreleased]: https://github.com/ayberkenis/jskelet/compare/v0.
|
|
560
|
+
[Unreleased]: https://github.com/ayberkenis/jskelet/compare/v0.6.0...HEAD
|
|
561
|
+
[0.6.0]: https://github.com/ayberkenis/jskelet/compare/v0.5.4...v0.6.0
|
|
507
562
|
[0.5.4]: https://github.com/ayberkenis/jskelet/compare/v0.5.3...v0.5.4
|
|
508
563
|
[0.5.3]: https://github.com/ayberkenis/jskelet/compare/v0.5.2...v0.5.3
|
|
509
564
|
[0.5.2]: https://github.com/ayberkenis/jskelet/compare/v0.5.1...v0.5.2
|
package/README.md
CHANGED
|
@@ -307,12 +307,13 @@ Anything reachable by a deeper path is internal and may change without notice.
|
|
|
307
307
|
## Deployment
|
|
308
308
|
|
|
309
309
|
The server is a plain Express 5 app, so anything that can run a Node process
|
|
310
|
-
works: a `Dockerfile` (see
|
|
311
|
-
a PaaS. Run `jskelet build` at image build time, put a
|
|
312
|
-
for TLS, and expose a health endpoint (the default
|
|
313
|
-
includes `/api/healthcheck`, so a route there is
|
|
314
|
-
Details, including cache sizing behind multiple
|
|
315
|
-
Redis tier, are in
|
|
310
|
+
works: a multi-stage `Dockerfile` (see [docs/10-dagitim.md](./docs/10-dagitim.md)),
|
|
311
|
+
a systemd unit, or a PaaS. Run `jskelet build` at image build time, put a
|
|
312
|
+
reverse proxy in front for TLS, and expose a health endpoint (the default
|
|
313
|
+
dev gate bypass list already includes `/api/healthcheck`, so a route there is
|
|
314
|
+
reachable in every mode). Details, including cache sizing behind multiple
|
|
315
|
+
instances and the optional Redis tier, are in
|
|
316
|
+
[docs/10-dagitim.md](./docs/10-dagitim.md) /
|
|
316
317
|
[docs/en/10-deployment.md](./docs/en/10-deployment.md).
|
|
317
318
|
|
|
318
319
|
## Documentation
|
|
@@ -343,7 +344,6 @@ apply to this repository.
|
|
|
343
344
|
```bash
|
|
344
345
|
npm --prefix examples/minimal install && npm --prefix examples/minimal run dev
|
|
345
346
|
npm --prefix examples/blog install && npm --prefix examples/blog run dev
|
|
346
|
-
npm --prefix examples/marketing install && npm --prefix examples/marketing run dev
|
|
347
347
|
npm --prefix examples/dashboard install && npm --prefix examples/dashboard run dev
|
|
348
348
|
```
|
|
349
349
|
|
|
@@ -352,13 +352,6 @@ npm --prefix examples/dashboard install && npm --prefix examples/dashboard run d
|
|
|
352
352
|
- **`examples/blog`** — dynamic routes, tag pages, every config section,
|
|
353
353
|
fragment-loaded tabs, a form, prewarm, RSS and sitemap, four islands. It
|
|
354
354
|
intentionally touches every surface of the framework.
|
|
355
|
-
- **`examples/marketing`** — the framework's own marketing site: comparison
|
|
356
|
-
table, changelog and download pages, long TTLs, prewarm covering every page.
|
|
357
|
-
The byte counts on the page are measured from that site's own build output, the
|
|
358
|
-
version details are read from the installed package, and the latency numbers
|
|
359
|
-
are measured in the browser; there are no invented benchmarks. It is also
|
|
360
|
-
bilingual — English at the root, Turkish under `/tr` — which shows how to build
|
|
361
|
-
a multi-language site on a framework that ships no i18n of its own.
|
|
362
355
|
- **`examples/dashboard`** — the opposite axis: per-visitor pages. A signed
|
|
363
356
|
cookie session, a `private: true` page that never enters the HTML cache, a
|
|
364
357
|
paginated table fragment, a CSRF-protected form that still works without
|
package/bin/jskelet.mjs
CHANGED
package/docs/02-mimari.md
CHANGED
|
@@ -36,9 +36,10 @@ JSkelet bu gözlemi mimarinin merkezine alır:
|
|
|
36
36
|
├─ rewrites(beforeFiles) config → proxy ya da req.url değişimi
|
|
37
37
|
├─ compression brotli/gzip pazarlığı (kalite 5)
|
|
38
38
|
├─ headers statik cache + config headers()
|
|
39
|
-
├─ devGate
|
|
39
|
+
├─ devGate gate açıksa ve token yoksa 404
|
|
40
40
|
├─ redirects config redirects(), ilk eşleşen kazanır
|
|
41
41
|
├─ trailingSlash config trailingSlash: true ise 308
|
|
42
|
+
├─ robots.txt kullanıcının gövdesine framework Disallow'u ekler
|
|
42
43
|
├─ staticPrecompressed build'de üretilmiş .br/.gz kopyalar (kalite 11)
|
|
43
44
|
├─ express.static public/ altındaki dosyalar
|
|
44
45
|
├─ (dev) devtools yalnızca NODE_ENV=development
|
|
@@ -71,6 +72,10 @@ sebebi var ve yer değiştirmek sessiz bozulmalara yol açıyor.
|
|
|
71
72
|
bile dışarıya sızdırmamalı. `trailingSlash` config redirects'ten sonra durur,
|
|
72
73
|
böylece açık kurallar istenen yolu önce görür; kanonik slash biçimi ikinci
|
|
73
74
|
adımda dayatılır.
|
|
75
|
+
- **`robots.txt`, statikten önce ve sıkıştırmanın içinde.** Uygulamanın
|
|
76
|
+
yazdığı gövde değişmez; framework kendi uçlarının `Disallow` kurallarını
|
|
77
|
+
sona ekler. Sıkıştırılmış bir kopyanın (`Content-Encoding`) üzerine
|
|
78
|
+
yazılmaz — ek düz metne konur, sıkıştırma dışarıda kalır.
|
|
74
79
|
- **`staticPrecompressed`, `express.static`ten önce.** Build'de üretilmiş
|
|
75
80
|
`.br`/`.gz` kopyalar varsa onlar servis edilir (brotli kalite 11); yoksa
|
|
76
81
|
istek altındaki `static`e düşer ve middleware anında sıkıştırır (kalite 5).
|
package/docs/03-routing.md
CHANGED
|
@@ -156,7 +156,9 @@ okuduğunda render önbelleğe yazılmaz), ama doğru yer bayrak. Ayrıntılar
|
|
|
156
156
|
## `fragment()` — layout'suz parça
|
|
157
157
|
|
|
158
158
|
Bir bölgeyi tazeleyen uçlar için. Layout basılmaz, yanıt `private, no-store` ve
|
|
159
|
-
ETag'siz gider, HTML önbelleğine hiç uğramaz.
|
|
159
|
+
ETag'siz gider, HTML önbelleğine hiç uğramaz. `/_fragment/` öneki
|
|
160
|
+
`robots.txt`'in altına eklenir; parça uçları dizine girmez
|
|
161
|
+
([04](./04-render-ve-sablonlar.md#robotstxt)).
|
|
160
162
|
|
|
161
163
|
```js
|
|
162
164
|
app.get(
|
|
@@ -503,6 +503,31 @@ return {
|
|
|
503
503
|
`renderHeadMeta(metadata)` fonksiyonu dışa açıktır; layout dışında (ör. bir
|
|
504
504
|
fragment ya da e-posta) aynı etiketleri üretmek gerekirse kullanılabilir.
|
|
505
505
|
|
|
506
|
+
## robots.txt
|
|
507
|
+
|
|
508
|
+
`robots.txt`'i uygulama yazar: `public/robots.txt` ya da düz bir route.
|
|
509
|
+
Framework bu gövdeyi değiştirmez; başarılı metin yanıtının **altına** bir
|
|
510
|
+
JSkelet notu ve `Disallow` kuralları ekler. Dosya ya da route yoksa framework
|
|
511
|
+
bir `robots.txt` uydurmaz.
|
|
512
|
+
|
|
513
|
+
Eklenen yollar:
|
|
514
|
+
|
|
515
|
+
- `/_jskelet/` — yönetim paneli, uzak görsel proxy, auth handoff
|
|
516
|
+
- `/__jskelet/` — geliştirme araçları
|
|
517
|
+
- `/_fragment/` — layout'suz parça yanıtları
|
|
518
|
+
|
|
519
|
+
Bu öneklerin dışına taşınmış bir uç da eklenir, ama yalnızca gerçekten
|
|
520
|
+
mount edildiyse: `admin.basePath`, `images.remote.path`,
|
|
521
|
+
`auth.crossSubdomainHandoff.path`. `brand.devBasePath` yalnızca
|
|
522
|
+
development'ta yazılır; production'da o yol uygulamanın kendi sayfası
|
|
523
|
+
olabilir.
|
|
524
|
+
|
|
525
|
+
Not, config'teki marka adıyla başlar (`brand.name`, varsayılan `JSkelet`).
|
|
526
|
+
Alttaki grup `User-agent: *` ile birlikte dosyada adı geçen diğer ajanları
|
|
527
|
+
da tekrarlar. Google, belirli bir ajana ait grubu `*` ile birleştirmez;
|
|
528
|
+
aynı ajanın ikinci grubunu birleştirir. Not dosyada zaten varsa ikinci kez
|
|
529
|
+
eklenmez.
|
|
530
|
+
|
|
506
531
|
## Dinamik OG görselleri
|
|
507
532
|
|
|
508
533
|
Next.js `ImageResponse` / `opengraph-image.tsx` karşılığı. JSX yok: kart
|
package/docs/06-cache.md
CHANGED
|
@@ -223,7 +223,11 @@ kabul edilebilir, çünkü fiyat gibi canlı alanlar istemcide WebSocket'ten
|
|
|
223
223
|
güncelleniyor.
|
|
224
224
|
|
|
225
225
|
Store LRU'dur: erişilen girdi sona taşınır, sınır (`cache().maxEntries`,
|
|
226
|
-
varsayılan 500) aşılınca en eski düşürülür.
|
|
226
|
+
varsayılan 500) aşılınca en eski düşürülür. Config 500'ün üstünü isteyebilir;
|
|
227
|
+
**800'ü geçemez** — daha yükseği uyarıyla 800'e çekilir. Bunun yanında süreç
|
|
228
|
+
içi HTML string + sıkıştırılmış gövde **256 MB**'yi geçemez. Sayı tavanının
|
|
229
|
+
altında kalan şişman sayfa veya `vary.host` kopyası da bu bütçede LRU ile
|
|
230
|
+
düşer. Tek sayfa 256 MB'den büyükse saklanmaz; yanıt o istekte yine gider.
|
|
227
231
|
|
|
228
232
|
## Ne önbelleğe yazılır
|
|
229
233
|
|
|
@@ -1145,9 +1149,9 @@ export default {
|
|
|
1145
1149
|
html: { "/": 60, "/haber/:slug": 300 },
|
|
1146
1150
|
prewarm: {
|
|
1147
1151
|
onVisit: {
|
|
1148
|
-
perPage: 20, // sayfa başına en fazla link
|
|
1149
|
-
concurrency: 2, //
|
|
1150
|
-
rps:
|
|
1152
|
+
perPage: 20, // sayfa başına en fazla link; tavan 20
|
|
1153
|
+
concurrency: 2, // tavan 2
|
|
1154
|
+
rps: 2, // tavan 2; 0 da 2'ye çekilir
|
|
1151
1155
|
},
|
|
1152
1156
|
},
|
|
1153
1157
|
};
|
|
@@ -1163,7 +1167,14 @@ Kurallar:
|
|
|
1163
1167
|
`private`, degraded veya `no-store` yanıtlar link çıkarmaz.
|
|
1164
1168
|
- Isıtma isteğinin kendi UA'sı (`brand.prewarmUserAgent`) tetiklemez — sonsuz
|
|
1165
1169
|
crawl olmaz.
|
|
1166
|
-
- Zaten taze olan yollar kuyruğa girmez.
|
|
1170
|
+
- Zaten taze olan yollar kuyruğa girmez. Anahtar `h=host|/yol?` biçimindedir;
|
|
1171
|
+
kontrol vary önekini ve sondaki `?` işaretini de görür. `vary.host` açıkken
|
|
1172
|
+
yalnızca bu isteğin host'u sıcak sayılır.
|
|
1173
|
+
- Bekleyen kuyruk en fazla 64 yoldur; taşan link bu turda alınmaz.
|
|
1174
|
+
- `perPage` 20, `rps` 2, `concurrency` 2 tavanıdır. Daha yükseği (ve `rps: 0`)
|
|
1175
|
+
uyarıyla tavana çekilir. Isıtma isteği loopback'e gider; `vary.host` açıkken
|
|
1176
|
+
public host `x-forwarded-host` ile taşınır, `h=127.0.0.1` diye ikinci girdi
|
|
1177
|
+
açılmaz.
|
|
1167
1178
|
- `nofollow`, `target="_blank"`, `data-no-prefetch`, `prewarmSkip` ve
|
|
1168
1179
|
`navigation.exclude` Speculation Rules ile aynı muafiyetleri paylaşır.
|
|
1169
1180
|
- Query string ısıtılmaz (varsayılan cache politikası query'yi dinamik sayar).
|
|
@@ -1306,8 +1317,8 @@ turlar upstream'e iki kat yük bindirirdi.
|
|
|
1306
1317
|
`accept-encoding: br, gzip` başlıklarıyla gider; ikincisi sıkıştırılmış gövdenin
|
|
1307
1318
|
de önbelleğe girmesi için.
|
|
1308
1319
|
|
|
1309
|
-
|
|
1310
|
-
|
|
1320
|
+
Dev gate açıksa ısıtma token'ı çerez olarak taşır; yoksa gate tüm sayfalara
|
|
1321
|
+
404 döner ve önbellek hiç dolmaz. `DEV_TOKEN` tek başına gate'i açmaz.
|
|
1311
1322
|
|
|
1312
1323
|
Dev panelindeki istek listesi ve terminal, `prewarmUserAgent` taşıyan istekleri
|
|
1313
1324
|
filtreler: yüzlerce ısıtma isteği görünümü doldurmasın. İlerleme baloncuğun
|
package/docs/07-yapilandirma.md
CHANGED
|
@@ -293,14 +293,28 @@ static: {
|
|
|
293
293
|
}
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
+
## `devGate`
|
|
297
|
+
|
|
298
|
+
**Tip:** `boolean` — **Varsayılan:** `false`
|
|
299
|
+
|
|
300
|
+
Yayına açılmamış ortamı gizler. **`DEV_TOKEN` tek başına siteyi kilitlemez.**
|
|
301
|
+
Paylaşılan bir task tanımı production'a da aynı değişkeni taşıyabilir; o
|
|
302
|
+
durumda ziyaretçi token vermek zorunda kalmaz, site açık kalır.
|
|
303
|
+
|
|
304
|
+
Gate'i açmak için `devGate: true` ya da `DEV_GATE=1`. İkisi de varken token
|
|
305
|
+
taşımayan isteğe 404 döner. `DEV_GATE=0` config'teki açığı da kapatır. Token
|
|
306
|
+
boşsa gate açık olsa da istekler geçer.
|
|
307
|
+
|
|
308
|
+
Ayrıntı: [09-dev-araclari.md](./09-dev-araclari.md).
|
|
309
|
+
|
|
296
310
|
## `devGateBypass`
|
|
297
311
|
|
|
298
312
|
**Tip:** `string[]` — **Varsayılan:**
|
|
299
313
|
`["/api/healthcheck", "/robots.txt", "/sitemap.xml", "/site.webmanifest", "/favicon.ico"]`
|
|
300
314
|
|
|
301
315
|
Dev gate'in hiçbir koşulda kapatmadığı **tam** yollar (önek değil, birebir
|
|
302
|
-
eşleşme).
|
|
303
|
-
|
|
316
|
+
eşleşme). Gate açıkken sağlık kontrolünün ve robots dosyalarının erişilebilir
|
|
317
|
+
kalması için. Verilirse varsayılanın yerine geçer.
|
|
304
318
|
|
|
305
319
|
Ayrıntı: [09-dev-araclari.md](./09-dev-araclari.md).
|
|
306
320
|
|
|
@@ -429,7 +443,9 @@ body > footer { view-transition-name: site-footer; }
|
|
|
429
443
|
::view-transition-new(root) { animation-duration: 180ms; }
|
|
430
444
|
```
|
|
431
445
|
|
|
432
|
-
Çalışan
|
|
446
|
+
Çalışan bir örnek için Tailwind `@source` ve view-transition CSS'ini kendi
|
|
447
|
+
uygulamanızın `styles/globals.css` dosyasına taşıyın; yukarıdaki bloklar
|
|
448
|
+
başlangıç noktasıdır.
|
|
433
449
|
|
|
434
450
|
**CSP kullanıyorsanız** kurallar satır içi bir `<script type="speculationrules">`
|
|
435
451
|
olarak basılır; `script-src` politikanızın buna izin vermesi gerekir.
|
|
@@ -755,13 +771,16 @@ HTML önbelleğinin girdi sınırı. Girdi başına yüz kilobayt düştüğü i
|
|
|
755
771
|
yükseltmek belleği hızla tüketir; on binlerce yollu bir siteyi buradan çözmeye
|
|
756
772
|
çalışmak yanlış katman, doğru yer `cache().data`.
|
|
757
773
|
|
|
774
|
+
**Tavan 800.** Daha yükseği yüklemede uyarıyla 800'e çekilir. Süreç içi HTML +
|
|
775
|
+
sıkıştırılmış gövde ayrıca 256 MB'yi geçemez; bu bütçe config'den yükseltilmez.
|
|
776
|
+
|
|
758
777
|
### `cache().data`
|
|
759
778
|
|
|
760
779
|
Upstream veri önbelleği (`withDataCache`). Ayrıntı: [06-cache.md](./06-cache.md).
|
|
761
780
|
|
|
762
781
|
| Alan | Tip | Varsayılan | Anlamı |
|
|
763
782
|
| --- | --- | --- | --- |
|
|
764
|
-
| `maxEntries` | `number` | `10000` | LRU girdi sınırı. JSON, HTML'e göre onlarca kat küçük olduğu için sınır yüksek. |
|
|
783
|
+
| `maxEntries` | `number` | `10000` | LRU girdi sınırı. JSON, HTML'e göre onlarca kat küçük olduğu için sınır yüksek. **Tavan 20000**; üstü uyarıyla kesilir. |
|
|
765
784
|
| `staleFactor` | `number` | `10` | TTL dolduktan sonra girdinin kaç TTL boyunca daha kullanılabileceği. `0` → bayat servis yok. |
|
|
766
785
|
|
|
767
786
|
### `cache().trackUpstream`
|
|
@@ -1001,13 +1020,13 @@ prewarm: {
|
|
|
1001
1020
|
| Alan | Tip | Varsayılan | Anlamı |
|
|
1002
1021
|
| --- | --- | --- | --- |
|
|
1003
1022
|
| `onVisit` | `true \| false \| object` | kapalı | Ziyaret tabanlı ısıtma |
|
|
1004
|
-
| `onVisit.perPage` | `number` | `20` | Sayfa başına üstten alta en fazla link |
|
|
1005
|
-
| `onVisit.concurrency` | `number` |
|
|
1006
|
-
| `onVisit.rps` | `number` |
|
|
1023
|
+
| `onVisit.perPage` | `number` | `20` | Sayfa başına üstten alta en fazla link. **Tavan 20** |
|
|
1024
|
+
| `onVisit.concurrency` | `number` | `2` | Paralel işçi. **Tavan 2** |
|
|
1025
|
+
| `onVisit.rps` | `number` | `2` | Saniyedeki tavan. **Tavan 2**; `0` da 2'ye çekilir |
|
|
1007
1026
|
|
|
1008
1027
|
```js
|
|
1009
1028
|
prewarm: {
|
|
1010
|
-
onVisit: { perPage: 20, rps:
|
|
1029
|
+
onVisit: { perPage: 20, rps: 2 },
|
|
1011
1030
|
}
|
|
1012
1031
|
```
|
|
1013
1032
|
|
|
@@ -1106,7 +1125,8 @@ basılmaz.
|
|
|
1106
1125
|
| `PORT` | `startServer` | `3000` | Dinlenecek port. Doluysa süreç başlamaz; `jskelet start|dev --murder` dinleyiciyi öldürür |
|
|
1107
1126
|
| `HOST` | `startServer` | `::` | Bağlanılacak arayüz. Varsayılan çift yığın dinler (IPv6 + IPv4); IPv6 yoksa `0.0.0.0`'a düşer |
|
|
1108
1127
|
| `JSKELET_SECRET` | `jskelet/cookies` | — | İmzalı cookie sırrı. `security.cookieSecret` verilmediğinde buradan okunur; ikisi de yoksa imzalı cookie API'si hata verir. [12](./12-panel-ve-oturum.md) |
|
|
1109
|
-
| `
|
|
1128
|
+
| `DEV_GATE` | `devGate` | kapalı | `1` gate'i açar, `0` config'te açık olsa da kapatır. `DEV_TOKEN` tek başına açmaz. [09](./09-dev-araclari.md) |
|
|
1129
|
+
| `DEV_TOKEN` | `devGate`, `prewarm` | — | Gate açıkken beklenen sır. Yoksa veya gate kapalıysa site açık kalır. Isıtma, gate açıkken token'ı çerez olarak taşır. [09](./09-dev-araclari.md) |
|
|
1110
1130
|
| `JSKELET_ADMIN` | `createApp` | — | Ayarlıysa yönetim panelini açar; `0` config'te açık olan paneli kapatır. Env config'i ezer, çünkü panel genelde bir arıza sırasında tek seferlik açılır. [06](./06-cache.md) |
|
|
1111
1131
|
| `JSKELET_LOG_BUCKET` | `logs.s3` | — | Log hedefi: bucket ya da `bucket/prefix` yolu. Credential ile birlikte varsa sink otomatik açılır |
|
|
1112
1132
|
| `JSKELET_S3_BUCKET` | `logs.s3` | — | `JSKELET_LOG_BUCKET` yoksa bucket; `JSKELET_S3_KEY_PREFIX` ile birleşir |
|
package/docs/09-dev-araclari.md
CHANGED
|
@@ -298,11 +298,19 @@ hiçbir şey yüklenmez.
|
|
|
298
298
|
|
|
299
299
|
## Dev gate — `DEV_TOKEN`
|
|
300
300
|
|
|
301
|
-
Yayına açılmamış bir ortamı gizlemek için
|
|
302
|
-
|
|
301
|
+
Yayına açılmamış bir ortamı gizlemek için. **Framework token'ı zorunlu tutmaz:**
|
|
302
|
+
`DEV_TOKEN` ortamda durması siteyi kilitlemez. Gate'i siz açarsınız.
|
|
303
303
|
|
|
304
304
|
```bash
|
|
305
|
-
DEV_TOKEN=uzun-rastgele-bir-dize npm start
|
|
305
|
+
DEV_GATE=1 DEV_TOKEN=uzun-rastgele-bir-dize npm start
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Aynı şey config ile:
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
export default {
|
|
312
|
+
devGate: true,
|
|
313
|
+
};
|
|
306
314
|
```
|
|
307
315
|
|
|
308
316
|
Erişim:
|
|
@@ -322,10 +330,12 @@ Davranış:
|
|
|
322
330
|
`/api/healthcheck`, `/robots.txt`, `/sitemap.xml`, `/site.webmanifest`,
|
|
323
331
|
`/favicon.ico`. Sağlık kontrolünüz farklı bir yolda ise bu listeye eklemeyi
|
|
324
332
|
unutmayın, aksi hâlde orkestratör 404 görür.
|
|
325
|
-
- `
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
333
|
+
- `devGate` kapalıyken (varsayılan) veya `DEV_TOKEN` boşken middleware isteği
|
|
334
|
+
olduğu gibi geçirir. Production task'ına sızmış bir `DEV_TOKEN` ziyaretçiden
|
|
335
|
+
token istemez; açılışta bir uyarı basılır.
|
|
336
|
+
- `DEV_GATE=0` config'te `devGate: true` olsa da gate'i kapatır.
|
|
337
|
+
- Isıtma, gate açıkken token'ı çerez olarak taşır; yoksa tüm sayfalar 404 alır
|
|
338
|
+
ve önbellek hiç dolmaz ([06-cache.md](./06-cache.md)).
|
|
329
339
|
|
|
330
340
|
Gate middleware zincirinde `headers`tan sonra, `redirects`ten **önce** durur:
|
|
331
341
|
yayına açılmamış bir ortam yönlendirme kurallarını bile dışarıya sızdırmamalı.
|