jskelet 0.5.5 → 0.6.0
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 +18 -13
- package/CHANGELOG.md +95 -0
- package/README.md +9 -7
- package/bin/jskelet.mjs +24 -10
- package/docs/01-baslangic.md +4 -3
- package/docs/02-mimari.md +4 -3
- package/docs/03-routing.md +11 -6
- package/docs/04-render-ve-sablonlar.md +35 -43
- package/docs/05-islands.md +12 -8
- package/docs/07-yapilandirma.md +40 -18
- package/docs/08-build.md +15 -9
- package/docs/09-dev-araclari.md +5 -1
- package/docs/10-dagitim.md +6 -1
- package/docs/11-tasima.md +51 -17
- package/docs/12-panel-ve-oturum.md +10 -4
- package/docs/README.md +7 -5
- package/docs/en/01-getting-started.md +4 -3
- package/docs/en/02-architecture.md +5 -5
- package/docs/en/03-routing.md +12 -7
- package/docs/en/04-rendering.md +47 -59
- package/docs/en/05-islands.md +13 -8
- package/docs/en/07-configuration.md +40 -20
- package/docs/en/08-build.md +16 -10
- package/docs/en/09-dev-tools.md +6 -1
- package/docs/en/10-deployment.md +6 -1
- package/docs/en/11-migration.md +51 -16
- package/docs/en/12-dashboards-and-sessions.md +9 -4
- package/docs/en/README.md +7 -5
- package/package.json +49 -14
- package/src/build/tasks/client.mjs +91 -10
- package/src/build/tasks/icons.mjs +11 -1
- package/src/client/index.js +2 -2
- package/src/compile/codegen.js +4 -0
- package/src/compile/compile-all.js +12 -21
- package/src/compile/expr.js +5 -0
- package/src/compile/parse.js +64 -8
- package/src/compile/resolve.js +3 -0
- package/src/config/defaults.js +12 -2
- package/src/config/index.js +1 -1
- package/src/dev-server.mjs +26 -3
- package/src/http/cookies-entry.js +1 -0
- package/src/http/cookies.js +18 -0
- package/src/logo.png +0 -0
- package/src/migrate/apply.mjs +262 -0
- package/src/migrate/babel.mjs +79 -0
- package/src/migrate/classify.mjs +155 -0
- package/src/migrate/config.mjs +126 -0
- package/src/migrate/fs-walk.mjs +191 -0
- package/src/migrate/parse.mjs +26 -0
- package/src/migrate/scan.mjs +177 -0
- package/src/migrate/transform/expr-source.mjs +168 -0
- package/src/migrate/transform/island.mjs +67 -0
- package/src/migrate/transform/jsx-to-component.mjs +302 -0
- package/src/migrate/transform/jsx-to-jsk.mjs +330 -0
- package/src/migrate/transform/page-split.mjs +435 -0
- package/src/migrate/write.mjs +81 -0
- package/src/migrate.mjs +171 -0
- package/src/server/auth/handoff.js +94 -11
- package/src/server/create-app.js +28 -10
- package/src/server/ejs-adapter.js +59 -0
- package/src/server/image-optimizer.js +94 -26
- package/src/server/port-guard.js +255 -0
- package/src/server/render.js +27 -9
- package/src/server/status-page.js +105 -4
- package/src/start.mjs +18 -3
- package/src/templates/layout.ejs +8 -28
- package/src/templates/layout.jsk +30 -0
- package/src/templates/layout.render.js +41 -0
- package/src/views/helpers/tags.js +86 -3
- package/types/build/resolve-peer.d.mts +13 -0
- package/types/client/dom.d.ts +55 -0
- package/types/client/form.d.ts +19 -0
- package/types/client/index.d.ts +20 -0
- package/types/client/registry.d.ts +53 -0
- package/types/client/safe-image.d.ts +19 -0
- package/types/client/shared-cookie.d.ts +82 -0
- package/types/client/store.d.ts +18 -0
- package/types/client/swap.d.ts +46 -0
- package/types/compile/codegen.d.ts +32 -0
- package/types/compile/compile-all.d.ts +42 -0
- package/types/compile/errors.d.ts +30 -0
- package/types/compile/expr.d.ts +67 -0
- package/types/compile/index.d.ts +10 -0
- package/types/compile/parse.d.ts +82 -0
- package/types/compile/resolve.d.ts +46 -0
- package/types/compile/scan-exports.d.ts +9 -0
- package/types/config/defaults.d.ts +449 -0
- package/types/config/index.d.ts +299 -0
- package/types/config/pattern.d.ts +38 -0
- package/types/http/control-flow.d.ts +45 -0
- package/types/http/cookies-entry.d.ts +5 -0
- package/types/http/cookies.d.ts +113 -0
- package/types/http/request-cache.d.ts +13 -0
- package/types/http/request-context.d.ts +67 -0
- package/types/http/shared-cookie.d.ts +73 -0
- package/types/index.d.ts +30 -0
- package/types/log.d.mts +153 -0
- package/types/server/admin/actions.d.ts +16 -0
- package/types/server/admin/auth.d.ts +52 -0
- package/types/server/admin/event-log.d.ts +38 -0
- package/types/server/admin/gate.d.ts +43 -0
- package/types/server/admin/inventory.d.ts +40 -0
- package/types/server/admin/mount.d.ts +6 -0
- package/types/server/admin/router.d.ts +6 -0
- package/types/server/admin/snapshot.d.ts +6 -0
- package/types/server/assets.d.ts +47 -0
- package/types/server/auth/handoff.d.ts +12 -0
- package/types/server/cache-deps.d.ts +16 -0
- package/types/server/cache-vary.d.ts +30 -0
- package/types/server/cloudflare.d.ts +163 -0
- package/types/server/create-app.d.ts +25 -0
- package/types/server/data-cache.d.ts +116 -0
- package/types/server/dev/devtools.d.ts +44 -0
- package/types/server/dev/report.d.ts +229 -0
- package/types/server/dev/socket.d.ts +17 -0
- package/types/server/dev/version-check.d.mts +15 -0
- package/types/server/ejs-adapter.d.ts +11 -0
- package/types/server/head-hints.d.ts +40 -0
- package/types/server/html-cache.d.ts +173 -0
- package/types/server/image-optimizer.d.ts +68 -0
- package/types/server/logs/access-middleware.d.ts +7 -0
- package/types/server/logs/file-sink.d.ts +17 -0
- package/types/server/logs/pipeline.d.ts +37 -0
- package/types/server/logs/s3-put.d.ts +85 -0
- package/types/server/logs/s3-sink.d.ts +26 -0
- package/types/server/metadata.d.ts +38 -0
- package/types/server/middleware/compression.d.ts +17 -0
- package/types/server/middleware/csrf.d.ts +4 -0
- package/types/server/middleware/dev-gate.d.ts +2 -0
- package/types/server/middleware/headers.d.ts +2 -0
- package/types/server/middleware/redirects.d.ts +2 -0
- package/types/server/middleware/static-precompressed.d.ts +5 -0
- package/types/server/middleware/trailing-slash.d.ts +11 -0
- package/types/server/middleware/upstream-proxy.d.ts +21 -0
- package/types/server/og-image.d.ts +149 -0
- package/types/server/port-guard.d.ts +50 -0
- package/types/server/prewarm.d.ts +128 -0
- package/types/server/redis.d.ts +163 -0
- package/types/server/render.d.ts +101 -0
- package/types/server/router.d.ts +5 -0
- package/types/server/status-page.d.ts +24 -0
- package/types/server/upstream-limiter.d.ts +123 -0
- package/types/server/upstream-tracking.d.ts +42 -0
- package/types/shared/cookie-domain.d.ts +29 -0
- package/types/templates/layout.render.d.ts +7 -0
- package/types/version.d.mts +10 -0
- package/types/views/components/loader.d.ts +5 -0
- package/types/views/helpers/html.d.ts +39 -0
- package/types/views/helpers/tags.d.ts +127 -0
package/AGENTS.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
Bu depo **JSkelet** framework'ünün kaynağıdır: Express 5 +
|
|
4
|
-
vanilla JS island'lar, Tailwind v4
|
|
5
|
-
|
|
3
|
+
Bu depo **JSkelet** framework'ünün kaynağıdır: Express 5 + build-time `.jsk`
|
|
4
|
+
sunucu render (EJS opsiyonel legacy peer), vanilla JS island'lar, Tailwind v4
|
|
5
|
+
ve süreç belleğinde yaşayan HTML TTL cache. React yok; framework kaynağı düz
|
|
6
|
+
JavaScript + JSDoc. Uygulama client island/entry'leri `.ts` olabilir; paket
|
|
7
|
+
`types/` altında `.d.ts` yayınlar. Sunucu route/hook/config hâlâ Node ESM
|
|
8
|
+
`.js`/`.mjs`.
|
|
6
9
|
|
|
7
10
|
Bir JSkelet **uygulamasında** çalışıyorsan (framework'ün kendisinde değil), aynı
|
|
8
11
|
kuralların uygulama tarafı karşılıkları için [docs/](./docs/README.md) yeterli;
|
|
@@ -96,16 +99,18 @@ parçalar ayrı ve `no-store` işaretli fragment uçlarında.
|
|
|
96
99
|
yalnızca `exports` haritasındaki belirteçler kullanılır (`jskelet`,
|
|
97
100
|
`jskelet/client`, `jskelet/html`, `jskelet/tags`).
|
|
98
101
|
|
|
99
|
-
##
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
|
|
102
|
+
## `.jsk` tuzakları
|
|
103
|
+
|
|
104
|
+
- İfade dilinde fonksiyon çağrısı, object/array literal ve atama yok — mantık
|
|
105
|
+
controller veya `views/components/*.js` içinde kalır. Layout’ta `asset()` /
|
|
106
|
+
`hasAsset()` için yerleşik `<Stylesheets />` / `<BodyScripts />` /
|
|
107
|
+
`<JsonLd />` kullan.
|
|
108
|
+
- `{#include "partials/x"}` aynı `data` nesnesini geçer; EJS’teki ikinci-argüman
|
|
109
|
+
locals yok — veriyi controller’da hazırla.
|
|
110
|
+
- `views/components/**` named export’ları PascalCase etiket olur; import yok.
|
|
111
|
+
- Kullanıcı verisi `{{ }}` ile kaçar; `{{{ }}}` yalnızca güvendiğin HTML için.
|
|
112
|
+
- Legacy EJS hâlâ varsa: `include` async’tir (`forEach` içinde `await` yok);
|
|
113
|
+
`<%= %>` / `<%- %>` ayrımına dikkat et; `ejs` opsiyonel peer olarak kurulmalı.
|
|
109
114
|
|
|
110
115
|
## Tailwind
|
|
111
116
|
|
package/CHANGELOG.md
CHANGED
|
@@ -10,19 +10,110 @@ one is listed under a **Breaking** heading.
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
+
- `jskelet dev --murder` / `jskelet start --murder`: if the listen port is
|
|
14
|
+
already taken, kill the listener and bind; without `--murder`, refuse to
|
|
15
|
+
start with a clear error (pid + hint) instead of a bare `EADDRINUSE`.
|
|
16
|
+
- Layout built-ins for `.jsk`: `Stylesheets`, `BodyScripts`, and `JsonLd`
|
|
17
|
+
(asset / script / JSON-LD loops without expression-language calls).
|
|
18
|
+
- Framework default layout as `src/templates/layout.jsk` with a checked-in
|
|
19
|
+
`layout.render.js` (`node scripts/compile-framework-layout.mjs`;
|
|
20
|
+
`--check` for drift). `jskelet/layout` points at the `.jsk` source;
|
|
21
|
+
legacy EJS copy remains at `jskelet/layout/ejs`.
|
|
22
|
+
- VS Code / Cursor JSK extension diagnostics (Problems on open/save) and
|
|
23
|
+
PascalCase component completions from `views/components` (v0.2.0).
|
|
24
|
+
- `<!DOCTYPE>` (and other `<!…>` declarations) parse correctly in `.jsk`
|
|
25
|
+
instead of hanging the compiler.
|
|
26
|
+
|
|
27
|
+
- `jskelet migrate` codemod for Next.js App Router → JSkelet: `scan` inventory,
|
|
28
|
+
`apply` (JSX pages → controller + `.jsk`, presentational components → HTML
|
|
29
|
+
string helpers, `"use client"` → island stubs), and `config` draft from
|
|
30
|
+
`next.config`. Ships with `@babel/parser` / `@babel/types`.
|
|
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
|
+
|
|
13
38
|
- Local flat `icons/` directory as the exclusive SVG sprite source when present
|
|
14
39
|
(`icons.dir`, default `"icons"`): `house.svg` / `house-bold.svg` file names,
|
|
15
40
|
XOR with `@phosphor-icons/core` (Phosphor only when the directory is absent).
|
|
16
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`).
|
|
17
45
|
|
|
18
46
|
### Fixed
|
|
19
47
|
|
|
48
|
+
- `jskelet dev` prints the real server failure (e.g. port already in use /
|
|
49
|
+
`--murder` hint) instead of only `server exited (code 1)` when the child
|
|
50
|
+
dies during startup.
|
|
51
|
+
- Marketing example icon sprite again includes trust-bar icons (`Package`,
|
|
52
|
+
`TextT`, `ShieldCheck`, …): `icons.scan` now covers `routes/` where those
|
|
53
|
+
names live after the `.jsk` migration (they were only declared in
|
|
54
|
+
controllers, not in scanned `lib`/`views`).
|
|
55
|
+
|
|
20
56
|
- Open Graph routes with a `.png` suffix (`/og/…/:slug.png`) now escape the
|
|
21
57
|
dot for Express 5 / path-to-regexp, so the handler matches again instead of
|
|
22
58
|
falling through to the HTML 404.
|
|
59
|
+
- Remote image optimizer no longer auto-follows redirects; each hop is
|
|
60
|
+
re-checked against `allowHosts`, blocked private addresses, and DNS
|
|
61
|
+
resolution (open-redirect SSRF).
|
|
62
|
+
|
|
63
|
+
### Breaking
|
|
64
|
+
|
|
65
|
+
- `ejs` is an optional peer dependency. Apps that only use `.jsk` need not
|
|
66
|
+
install it; apps that still have `.ejs` views or layouts must
|
|
67
|
+
`npm i ejs`. Missing EJS when an `.ejs` file is rendered throws a clear
|
|
68
|
+
install/migrate hint.
|
|
69
|
+
- `jskelet/layout` now resolves to `layout.jsk` (was `layout.ejs`). Use
|
|
70
|
+
`jskelet/layout/ejs` for the legacy file.
|
|
71
|
+
|
|
72
|
+
- `auth.crossSubdomainHandoff` mint requires a non-empty
|
|
73
|
+
`allowedCookieNames` list; `true` alone no longer accepts arbitrary cookie
|
|
74
|
+
names.
|
|
75
|
+
- Production client builds omit sourcemaps (development still emits them).
|
|
76
|
+
- Secret-like `clientEnv` key names fail the build instead of being inlined.
|
|
23
77
|
|
|
24
78
|
### Changed
|
|
25
79
|
|
|
80
|
+
- Examples (`minimal`, `blog`, `dashboard`, `marketing`) use `.jsk` only
|
|
81
|
+
(layouts, pages, partials); EJS files removed from those trees.
|
|
82
|
+
- Template compiler: unknown PascalCase components fail the build; clearer
|
|
83
|
+
errors for forbidden function calls, unknown includes (with location), and
|
|
84
|
+
unclosed `{#if}` / `{#each}` at EOF; icon scan recognizes `<Icon name="…" />`.
|
|
85
|
+
- Docs / AGENTS / README present build-time `.jsk` as the default story; EJS
|
|
86
|
+
is documented as an optional legacy peer.
|
|
87
|
+
|
|
88
|
+
- VS Code / Cursor extension (`extensions/vscode-jsk`) uses the new 3D `.jsk`
|
|
89
|
+
mark as both the marketplace extension icon and the explorer file icon for
|
|
90
|
+
`*.jsk`. Packages as a standalone VSIX (vendors `src/compile`) for
|
|
91
|
+
Marketplace publish.
|
|
92
|
+
- `@babel/parser` and `@babel/types` are optional peers used only by migrate
|
|
93
|
+
(JSX/TSX parsing). They are no longer installed with every `jskelet`
|
|
94
|
+
install; missing peers throw an install hint (`npm i -D @babel/parser
|
|
95
|
+
@babel/types`). Unused `@babel/traverse` was dropped.
|
|
96
|
+
|
|
97
|
+
- Auth handoff mint mounts **after** CSRF so origin checks apply to
|
|
98
|
+
`POST /_jskelet/auth/handoff`.
|
|
99
|
+
- Docs (TR/EN): stronger `trustProxy` / `csrf.token` guidance and a fuller
|
|
100
|
+
security-headers example under `headers()`.
|
|
101
|
+
- Marketing copy (EN/TR) and how-it-works examples present `.jsk` as the
|
|
102
|
+
default template surface instead of EJS; the compare column for hand-written
|
|
103
|
+
Express + EJS stays as a competitor. Scaffold and migrate mappings name
|
|
104
|
+
`.jsk` pages and layouts.
|
|
105
|
+
- Framework and marketing brand mark: new geometric logo at `src/logo.png`
|
|
106
|
+
(admin / devtools) and `examples/marketing/public/logo.png`, replacing the
|
|
107
|
+
CDN-hosted mark. Marketing serves local favicons (`favicon.ico`, 16/32 PNG,
|
|
108
|
+
apple-touch-icon) via metadata `extraTags`.
|
|
109
|
+
- In development (`NODE_ENV=development`), 5xx responses show a diagnostic
|
|
110
|
+
page with the error message and stack trace instead of the polished 500
|
|
111
|
+
status page / `hooks.error()`. Production still returns the minimal status
|
|
112
|
+
page with no internals.
|
|
113
|
+
- Marketing fit copy (EN/TR) treats signed-in dashboards and per-visitor
|
|
114
|
+
panels as a supported path (`private: true`, fragments) instead of a
|
|
115
|
+
“wrong choice”; the poor-fit column now names SPA shells, collaborative
|
|
116
|
+
client trees, streaming/RSC, and built-in real-time transport.
|
|
26
117
|
- Marketing example copy (EN/TR) reflects 0.5.x cache surfaces: host `vary`,
|
|
27
118
|
early refresh, classic vs `onVisit` prewarm, local `icons/`, shared cookies,
|
|
28
119
|
and `opengraph-image` → `ogHandler` on the migrate table. Pages now serve
|
|
@@ -30,6 +121,10 @@ one is listed under a **Breaking** heading.
|
|
|
30
121
|
- Marketing changelog page restyled like a release-notes browser: measured
|
|
31
122
|
summary cards, search and newest/oldest sort, paginated open release cards
|
|
32
123
|
with Latest / Released badges and GitHub links (still driven by `CHANGELOG.md`).
|
|
124
|
+
- Marketing example visual language tightened toward the dark cyan glass look:
|
|
125
|
+
shared `glass-panel` surfaces site-wide, numbered lit feature cards, a
|
|
126
|
+
3D stack illustration on the home hero, and rotating cyan border beams on
|
|
127
|
+
lit panels.
|
|
33
128
|
|
|
34
129
|
## [0.5.4] - 2026-09-18
|
|
35
130
|
|
package/README.md
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
the product.
|
|
5
5
|
|
|
6
6
|
JSkelet renders **complete HTML** on an Express 5 server from build-time
|
|
7
|
-
**`.jsk` templates** (EJS
|
|
8
|
-
**islands**, compiles CSS into a **single Tailwind v4
|
|
9
|
-
of ISR keeps an in-process **HTML TTL cache** with
|
|
10
|
-
optional Redis sharing and path-based
|
|
11
|
-
plain JavaScript with JSDoc
|
|
7
|
+
**`.jsk` templates** (optional EJS peer for legacy `.ejs`), adds interactivity
|
|
8
|
+
through vanilla JS **islands**, compiles CSS into a **single Tailwind v4
|
|
9
|
+
stylesheet**, and instead of ISR keeps an in-process **HTML TTL cache** with
|
|
10
|
+
stale-while-revalidate — plus optional Redis sharing and path-based
|
|
11
|
+
invalidation. No React — the framework source is plain JavaScript with JSDoc;
|
|
12
|
+
apps can write client islands and entries in TypeScript, and the published
|
|
13
|
+
package ships declaration files.
|
|
12
14
|
|
|
13
15
|
[](https://www.npmjs.com/package/jskelet)
|
|
14
16
|
[](https://nodejs.org)
|
|
@@ -282,9 +284,9 @@ The complete reference — every field, default and failure mode — is
|
|
|
282
284
|
|
|
283
285
|
| Command | What it does |
|
|
284
286
|
| --- | --- |
|
|
285
|
-
| `jskelet dev` | Watch build plus server, live reload, devtools overlay |
|
|
287
|
+
| `jskelet dev` | Watch build plus server, live reload, devtools overlay. `--murder` kills whatever already holds `PORT` and starts. |
|
|
286
288
|
| `jskelet build` | Production build: templates → fonts → sprite → CSS → JS → images → manifest → precompress |
|
|
287
|
-
| `jskelet start` | Production server; builds first if output is missing |
|
|
289
|
+
| `jskelet start` | Production server; builds first if output is missing. `--murder` same as for `dev`. |
|
|
288
290
|
| `jskelet init` | Scaffolds a feature-first `.jsk` skeleton into the current directory |
|
|
289
291
|
| `jskelet generate` | Scaffolds a `feature` / `page` / `island` |
|
|
290
292
|
|
package/bin/jskelet.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* JSkelet CLI.
|
|
4
4
|
*
|
|
5
|
-
* jskelet dev
|
|
6
|
-
* jskelet build
|
|
7
|
-
* jskelet start
|
|
5
|
+
* jskelet dev [--murder] build watch + sunucu, canlı yenileme, dev overlay
|
|
6
|
+
* jskelet build tek seferlik prod build (fontlar, sprite, CSS, JS, görseller)
|
|
7
|
+
* jskelet start [--murder] prod sunucu (build eksikse önce üretir)
|
|
8
8
|
* jskelet init bulunduğun dizine minimal iskelet kurar
|
|
9
9
|
* jskelet generate feature / page / island iskeleti
|
|
10
|
+
* jskelet migrate Next.js App Router → JSkelet codemod
|
|
10
11
|
*
|
|
11
12
|
* Alt komutlar ayrı süreçlerde çalışır. Sebep: `dev` iki uzun ömürlü süreci
|
|
12
13
|
* (build watch + sunucu) yönetiyor ve sunucunun ESM resolve hook'larına
|
|
@@ -102,15 +103,28 @@ switch (command) {
|
|
|
102
103
|
break;
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
case "migrate": {
|
|
107
|
+
const { migrate } = await import("../src/migrate.mjs");
|
|
108
|
+
try {
|
|
109
|
+
await migrate(process.cwd(), rest);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
process.stderr.write(`${error instanceof Error ? error.message : error}\n`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
|
|
105
117
|
default: {
|
|
106
118
|
const known = command ? `unknown command: ${command}\n\n` : "";
|
|
107
119
|
process.stderr.write(
|
|
108
|
-
`${known}usage: jskelet <dev|build|start|init|generate
|
|
109
|
-
" dev
|
|
110
|
-
" build
|
|
111
|
-
" start
|
|
112
|
-
" init
|
|
113
|
-
" generate
|
|
120
|
+
`${known}usage: jskelet <dev|build|start|init|generate|migrate> [options]\n\n` +
|
|
121
|
+
" dev [--murder] build watch + server (live reload, dev overlay)\n" +
|
|
122
|
+
" build production build\n" +
|
|
123
|
+
" start [--murder] production server\n" +
|
|
124
|
+
" init scaffold a minimal skeleton in the current directory\n" +
|
|
125
|
+
" generate scaffold feature | page | island\n" +
|
|
126
|
+
" migrate Next.js App Router → JSkelet codemod (scan | apply | config)\n\n" +
|
|
127
|
+
" --murder if the listen port is busy, kill the listener and start\n",
|
|
114
128
|
);
|
|
115
129
|
process.exit(command ? 1 : 0);
|
|
116
130
|
}
|
package/docs/01-baslangic.md
CHANGED
|
@@ -249,11 +249,12 @@ resolve hook'larına (`--import`) süreç başlangıcında ihtiyaç duyması.
|
|
|
249
249
|
|
|
250
250
|
| Komut | Ne yapar |
|
|
251
251
|
| --- | --- |
|
|
252
|
-
| `jskelet dev` | Build watch + sunucu, tek terminalde. Canlı yenileme, CSS hot-swap, dev overlay. `NODE_ENV=development`. |
|
|
252
|
+
| `jskelet dev` | Build watch + sunucu, tek terminalde. Canlı yenileme, CSS hot-swap, dev overlay. `NODE_ENV=development`. Port doluysa başlamaz; `--murder` dinleyiciyi öldürüp bağlar. |
|
|
253
253
|
| `jskelet build` | Tek seferlik prod build: fontlar → ikon sprite → CSS → client JS → görseller → manifest → precompress. `NODE_ENV` verilmemişse `production`. |
|
|
254
|
-
| `jskelet start` | Prod sunucu. Build çıktısı yoksa önce üretir. `NODE_ENV` verilmemişse `production`. |
|
|
254
|
+
| `jskelet start` | Prod sunucu. Build çıktısı yoksa önce üretir. `NODE_ENV` verilmemişse `production`. Port davranışı `dev` ile aynı (`--murder`). |
|
|
255
255
|
| `jskelet init` | Bulunduğun dizine feature-first `.jsk` iskeleti kurar; var olan dosyalara dokunmaz. |
|
|
256
256
|
| `jskelet generate` | `feature` / `page` / `island` iskeleti üretir. |
|
|
257
|
+
| `jskelet migrate` | Next.js App Router → JSkelet codemod (`scan` / `apply` / `config`). [11-tasima.md](./11-tasima.md). |
|
|
257
258
|
|
|
258
259
|
Bilinmeyen bir komut ya da argümansız çağrı kullanım metnini basar.
|
|
259
260
|
|
|
@@ -280,7 +281,7 @@ yalnızca bu belirteçleri kullanın:
|
|
|
280
281
|
| `jskelet/tags` | `link`, `image`, `icon`, `preloadImage`, `toKebab` |
|
|
281
282
|
| `jskelet/log` | Konsol çıktısı yardımcıları (`banner`, `event`, `task`, `size`, `ms`, …) |
|
|
282
283
|
| `jskelet/register` | `node --import jskelet/register` ile alias + uzantı hook'ları |
|
|
283
|
-
| `jskelet/layout` | Framework'ün varsayılan `layout.
|
|
284
|
+
| `jskelet/layout` | Framework'ün varsayılan `layout.jsk` dosyasının yolu |
|
|
284
285
|
|
|
285
286
|
## Sırada ne var
|
|
286
287
|
|
package/docs/02-mimari.md
CHANGED
|
@@ -51,7 +51,7 @@ JSkelet bu gözlemi mimarinin merkezine alır:
|
|
|
51
51
|
│ └─ withHtmlCache TTL + stale-while-revalidate
|
|
52
52
|
│ └─ withUpstreamTracking
|
|
53
53
|
│ └─ withRequestCache
|
|
54
|
-
│ └─ controller → renderPage → EJS
|
|
54
|
+
│ └─ controller → renderPage → .jsk (veya legacy EJS)
|
|
55
55
|
├─ 404 → hooks.notFound()
|
|
56
56
|
└─ hata yönetimi redirect/notFound + 500 fallback
|
|
57
57
|
```
|
|
@@ -254,8 +254,9 @@ teşhisi zor sorunlara dönüşüyor.
|
|
|
254
254
|
|
|
255
255
|
## Neden bu bağımlılık listesi
|
|
256
256
|
|
|
257
|
-
Çalışma zamanı bağımlılıkları
|
|
258
|
-
`tailwind-merge`.
|
|
257
|
+
Çalışma zamanı bağımlılıkları üçtür: `express`, `esbuild`,
|
|
258
|
+
`tailwind-merge`. `ejs` yalnızca legacy `.ejs` şablonları için opsiyonel peer'dır.
|
|
259
|
+
Geri kalan her şey (Tailwind, PostCSS, lightningcss, sharp,
|
|
259
260
|
Phosphor ikonları) **opsiyonel peer bağımlılığıdır** ve yoksa ilgili build adımı
|
|
260
261
|
atlanır.
|
|
261
262
|
|
package/docs/03-routing.md
CHANGED
|
@@ -210,7 +210,7 @@ Controller `async (ctx) => sayfa` biçimindedir ve şu alanları döndürebilir:
|
|
|
210
210
|
|
|
211
211
|
| Alan | Tip | Varsayılan | Anlamı |
|
|
212
212
|
| --- | --- | --- | --- |
|
|
213
|
-
| `view` | `string` | — | `views/` altındaki şablon yolu, uzantısız: `"pages/home"` → `views/pages/home.ejs
|
|
213
|
+
| `view` | `string` | — | `views/` altındaki şablon yolu, uzantısız: `"pages/home"` → `views/pages/home.jsk` (yoksa legacy `.ejs`). |
|
|
214
214
|
| `data` | `object` | `{}` | Şablona local olarak geçen veriler. |
|
|
215
215
|
| `metadata` | `object` | `{}` | `<head>` etiketlerine çevrilir; `hooks.metadata()` çıktısının üzerine biner. Şema: [04-render-ve-sablonlar.md](./04-render-ve-sablonlar.md). |
|
|
216
216
|
| `status` | `number` | `200` | HTTP durum kodu. Yalnızca 200 önbelleğe yazılır. |
|
|
@@ -326,12 +326,17 @@ hata yöneticisi devreye girer, hatayı loglar ve framework'ün kendi hata sayfa
|
|
|
326
326
|
`Cache-Control: no-store` ile döner. Durum kodu hatanın `statusCode` (ya da
|
|
327
327
|
`status`) alanından okunur; 400–599 aralığında değilse 500 kullanılır.
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
**Development** (`NODE_ENV=development`, yani `jskelet dev`): 5xx yanıtlarında
|
|
330
|
+
gömülü 500 sayfası ve `hooks.error()` atlanır; mesaj, yığın izi ve varsa
|
|
331
|
+
`cause` zinciri içeren bir teşhis sayfası döner. 4xx (404 vb.) development'ta
|
|
332
|
+
da her zamanki gibi durum sayfasıdır.
|
|
333
333
|
|
|
334
|
-
|
|
334
|
+
**Production**: framework'ün sayfası bilinçli olarak yalın — durum kodu, tek
|
|
335
|
+
satır başlık ve tek satır açıklama. Marka adı, gezinme ya da hata ayrıntısı
|
|
336
|
+
taşımaz; sunucunun içi ziyaretçiye açılmaz. Dil `brand.lang`ten gelir (`tr` ve
|
|
337
|
+
`en` hazır, diğerleri `en`e düşer).
|
|
338
|
+
|
|
339
|
+
Kendi sayfanı vermek için `hooks.error()` (yalnızca production / 4xx):
|
|
335
340
|
|
|
336
341
|
```js
|
|
337
342
|
// jskelet.config.mjs
|
|
@@ -51,7 +51,7 @@ controller data → import edilmiş render(data, helpers) → HTML
|
|
|
51
51
|
{/if}
|
|
52
52
|
|
|
53
53
|
{#each items as item, i}
|
|
54
|
-
<li data-i="
|
|
54
|
+
<li :data-i="i">{{ item }}</li>
|
|
55
55
|
{/each}
|
|
56
56
|
|
|
57
57
|
<Link href="/" text="Home" />
|
|
@@ -99,19 +99,30 @@ code --install-extension extensions/vscode-jsk
|
|
|
99
99
|
|
|
100
100
|
Ayrıntılar uzantı README'sinde.
|
|
101
101
|
|
|
102
|
+
### Yerleşik layout etiketleri
|
|
103
|
+
|
|
104
|
+
`.jsk` ifade dilinde `asset()` / `hasAsset()` çağrılamaz. Layout’ta stylesheet,
|
|
105
|
+
script ve JSON-LD döngüleri için yerleşikler:
|
|
106
|
+
|
|
107
|
+
| Etiket | Props | Çıktı |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| `Stylesheets` | `styles` | `app.css` + sayfa sheet’leri (`data-jskelet-css`) |
|
|
110
|
+
| `BodyScripts` | `entries`, `devtools`, `devBasePath` | `main.js`, entry’ler, isteğe bağlı overlay |
|
|
111
|
+
| `JsonLd` | `items` (`structuredData`) | `application/ld+json` script’leri |
|
|
112
|
+
|
|
102
113
|
### EJS ile birlikte yaşam
|
|
103
114
|
|
|
104
115
|
Aynı `view` id için derlenmiş `.jsk` varsa o kullanılır; yoksa `.ejs` dosyası
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
**yalnızca `ejs` peer’i kuruluysa** render edilir. `jskelet init` yeni iskeleti
|
|
117
|
+
`.jsk` ile kurar.
|
|
107
118
|
|
|
108
|
-
## EJS motoru (legacy)
|
|
119
|
+
## EJS motoru (legacy peer)
|
|
109
120
|
|
|
110
|
-
EJS
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
EJS opsiyonel peer bağımlılıktır (`npm i ejs`). `.jsk`-only uygulamalar kurmak
|
|
122
|
+
zorunda değildir. Bir `.ejs` view veya layout istendiğinde paket uygulamadan
|
|
123
|
+
yüklenir; yoksa göç yolunu gösteren bir hata fırlatılır.
|
|
113
124
|
|
|
114
|
-
Ayarlar:
|
|
125
|
+
Motor ilk EJS render’da bir kez kurulur. Ayarlar:
|
|
115
126
|
|
|
116
127
|
| Ayar | Değer | Sebebi |
|
|
117
128
|
| --- | --- | --- |
|
|
@@ -120,9 +131,7 @@ Ayarlar:
|
|
|
120
131
|
| `rmWhitespace` | `true` | çıktı boyutu |
|
|
121
132
|
| `async` | `true` | şablon içinde `await` kullanılabilir |
|
|
122
133
|
|
|
123
|
-
Gömülü kullanımlar (test, script) için `resetRenderEngine()` dışa açık
|
|
124
|
-
dosyaları değişince kaydı yeniler. Dev sunucusu süreci yeniden başlattığı için
|
|
125
|
-
normal akışta gerekmez.
|
|
134
|
+
Gömülü kullanımlar (test, script) için `resetRenderEngine()` dışa açık.
|
|
126
135
|
|
|
127
136
|
## Layout
|
|
128
137
|
|
|
@@ -130,50 +139,33 @@ normal akışta gerekmez.
|
|
|
130
139
|
|
|
131
140
|
1. `jskelet.config.mjs` → `layout` verilmişse o kullanılır. Yol, **views
|
|
132
141
|
dizininin üst dizinine** göre çözülür: `views` varsayılansa
|
|
133
|
-
`layout: "views/ozel.
|
|
142
|
+
`layout: "views/ozel.jsk"` → `<root>/views/ozel.jsk`.
|
|
134
143
|
2. Verilmemişse `views/layout.jsk` (derlenmiş) varsa o kullanılır.
|
|
135
|
-
3. Yoksa `views/layout.ejs` varsa o kullanılır.
|
|
144
|
+
3. Yoksa `views/layout.ejs` varsa o kullanılır (EJS peer gerekir).
|
|
136
145
|
4. O da yoksa framework'ün kendi minimal layout'u kullanılır
|
|
137
|
-
(`node_modules/jskelet/src/templates/layout.
|
|
138
|
-
`jskelet/layout`
|
|
146
|
+
(`node_modules/jskelet/src/templates/layout.jsk`, `jskelet/layout`;
|
|
147
|
+
legacy kopya `jskelet/layout/ejs`).
|
|
139
148
|
|
|
140
149
|
Üçüncü seçenek yeni bir projenin tek route ile çalışabilmesi için var. Kendi
|
|
141
|
-
layout'unuza geçmenin en pratik yolu o dosyayı `views/layout.
|
|
150
|
+
layout'unuza geçmenin en pratik yolu o dosyayı `views/layout.jsk` olarak
|
|
142
151
|
kopyalamaktır.
|
|
143
152
|
|
|
144
153
|
### Framework'ün varsayılan layout'u
|
|
145
154
|
|
|
146
|
-
```
|
|
155
|
+
```jsk
|
|
147
156
|
<!DOCTYPE html>
|
|
148
|
-
<html lang="
|
|
157
|
+
<html :lang="lang">
|
|
149
158
|
<head>
|
|
150
159
|
<meta charset="utf-8">
|
|
151
160
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
<% styles.forEach(function (sheet) { %>
|
|
157
|
-
<% if (hasAsset(sheet)) { %>
|
|
158
|
-
<link rel="stylesheet" href="<%= asset(sheet) %>" data-jskelet-css="<%= sheet %>">
|
|
159
|
-
<% } %>
|
|
160
|
-
<% }); %>
|
|
161
|
-
<%- headMeta %>
|
|
162
|
-
<% structuredData.forEach(function (item) { %>
|
|
163
|
-
<script type="application/ld+json"><%- jsonScript(item) %></script>
|
|
164
|
-
<% }); %>
|
|
161
|
+
{{{ extraHead }}}
|
|
162
|
+
<Stylesheets :styles="styles" />
|
|
163
|
+
{{{ headMeta }}}
|
|
164
|
+
<JsonLd :items="structuredData" />
|
|
165
165
|
</head>
|
|
166
|
-
<body class="
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
<script type="module" src="<%= asset('main.js') %>"></script>
|
|
170
|
-
<% } %>
|
|
171
|
-
<% entries.forEach(function (entry) { %>
|
|
172
|
-
<script type="module" src="<%= asset(entry) %>"></script>
|
|
173
|
-
<% }); %>
|
|
174
|
-
<% if (devtools) { %>
|
|
175
|
-
<script type="module" src="<%= devBasePath %>/overlay.js"></script>
|
|
176
|
-
<% } %>
|
|
166
|
+
<body :class="bodyClass">
|
|
167
|
+
{{{ body }}}
|
|
168
|
+
<BodyScripts :entries="entries" :devtools="devtools" :devBasePath="devBasePath" />
|
|
177
169
|
</body>
|
|
178
170
|
</html>
|
|
179
171
|
```
|
|
@@ -187,7 +179,7 @@ Dikkat edilecek noktalar:
|
|
|
187
179
|
sheet'leri de aynı şekilde basılır. Build çalışmadıysa `hasAsset` false olur
|
|
188
180
|
ve etiket hiç basılmaz.
|
|
189
181
|
- **`hasAsset` kontrolleri** build eksikken sayfanın 404 veren dosyaları
|
|
190
|
-
istememesini sağlar.
|
|
182
|
+
istememesini sağlar (`Stylesheets` / `BodyScripts` içinde).
|
|
191
183
|
- **Devtools script'i** yalnızca `NODE_ENV=development` iken basılır; prod
|
|
192
184
|
çıktısında hiç yoktur.
|
|
193
185
|
|
package/docs/05-islands.md
CHANGED
|
@@ -118,25 +118,29 @@ Pratik sonucu: bir modal'ı `hidden` başlatabilirsiniz, island'ı yine bağlan
|
|
|
118
118
|
```
|
|
119
119
|
client/
|
|
120
120
|
├── entries/
|
|
121
|
-
│ ├── main.js her sayfada yüklenen ortak bootstrap
|
|
121
|
+
│ ├── main.js her sayfada yüklenen ortak bootstrap (veya main.ts)
|
|
122
122
|
│ └── chart.js yalnızca isteyen sayfalarda
|
|
123
123
|
└── islands/
|
|
124
|
-
├── counter.js
|
|
124
|
+
├── counter.ts .js veya .ts
|
|
125
125
|
└── chart.js
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
`client/entries/*.js` içindeki **her dosya bir esbuild entry'sidir**.
|
|
129
|
-
layout tarafından her sayfada yüklenir (manifest'te
|
|
130
|
-
yalnızca onları isteyen sayfalarda yüklenir
|
|
128
|
+
`client/entries/*.{js,ts,mts}` içindeki **her dosya bir esbuild entry'sidir**.
|
|
129
|
+
`main.js` (veya `main.ts`) layout tarafından her sayfada yüklenir (manifest'te
|
|
130
|
+
varsa). Ek entry'ler yalnızca onları isteyen sayfalarda yüklenir. Aynı stem için
|
|
131
|
+
iki uzantı (`main.js` + `main.ts`) build hatasıdır.
|
|
131
132
|
|
|
132
133
|
```js
|
|
133
|
-
// controller
|
|
134
|
+
// controller — manifest anahtarı her zaman *.js kalır
|
|
134
135
|
return { view: "pages/markets", entries: ["chart.js"] };
|
|
135
136
|
```
|
|
136
137
|
|
|
137
138
|
Layout `entries` dizisindeki her adı `asset(entry)` ile çözüp bir
|
|
138
|
-
`<script type="module">` basar. Ad manifest anahtarıdır,
|
|
139
|
-
|
|
139
|
+
`<script type="module">` basar. Ad manifest anahtarıdır (`chart.js`), kaynak
|
|
140
|
+
dosya `chart.ts` olsa bile hash'siz anahtar `.js` kalır.
|
|
141
|
+
|
|
142
|
+
Paylaşılan `@/lib` modülleri sunucuda da import ediliyorsa **`.js` kalsın** —
|
|
143
|
+
Node runtime `.ts` çözmez; `.ts` yalnızca esbuild client hattında derlenir.
|
|
140
144
|
|
|
141
145
|
Kod bölme (`splitting: true`) açık: iki entry'nin paylaştığı modüller ortak bir
|
|
142
146
|
chunk'a çıkar ve iki kez indirilmez.
|
package/docs/07-yapilandirma.md
CHANGED
|
@@ -51,7 +51,7 @@ export default {
|
|
|
51
51
|
lang: "tr",
|
|
52
52
|
},
|
|
53
53
|
|
|
54
|
-
layout: "views/layout.
|
|
54
|
+
layout: "views/layout.jsk",
|
|
55
55
|
routes: ["./routes/10-pages.mjs", "./routes/99-catch-all.mjs"],
|
|
56
56
|
trailingSlash: false,
|
|
57
57
|
|
|
@@ -208,26 +208,32 @@ session id taşımak için handoff köprüsünü açar.
|
|
|
208
208
|
|
|
209
209
|
| Alan | Tip | Varsayılan | Anlamı |
|
|
210
210
|
| --- | --- | --- | --- |
|
|
211
|
-
| `crossSubdomainHandoff` | `boolean \| object` | `false` |
|
|
211
|
+
| `crossSubdomainHandoff` | `boolean \| object` | `false` | Açıkken `POST /_jskelet/auth/handoff` + `?handoff=` redeem. Object: `allowedCookieNames` (zorunlu), `ttlSeconds?`, `path?`, `maxValueBytes?`, `maxPendingTickets?`, `maxMintsPerIpPerMinute?` |
|
|
212
212
|
|
|
213
213
|
```js
|
|
214
214
|
auth: {
|
|
215
|
-
crossSubdomainHandoff: {
|
|
215
|
+
crossSubdomainHandoff: {
|
|
216
|
+
allowedCookieNames: ["sid"],
|
|
217
|
+
ttlSeconds: 60,
|
|
218
|
+
},
|
|
216
219
|
},
|
|
217
220
|
```
|
|
218
221
|
|
|
219
|
-
|
|
222
|
+
Mint uç noktası CSRF middleware'inden **sonra** mount edilir (origin kontrolü).
|
|
223
|
+
Cookie adı allowlist dışındaysa veya RFC 6265 token değilse 400. Ayrıntı:
|
|
224
|
+
[12-panel-ve-oturum.md](./12-panel-ve-oturum.md).
|
|
220
225
|
|
|
221
226
|
## `layout`
|
|
222
227
|
|
|
223
228
|
**Tip:** `string` — **Varsayılan:** yok (otomatik çözüm)
|
|
224
229
|
|
|
225
|
-
Layout `.
|
|
226
|
-
göre çözülür, yani varsayılan `views` ile
|
|
227
|
-
`<root>/views/ozel.
|
|
230
|
+
Layout dosyasının yolu (`.jsk` veya legacy `.ejs`). Verilen değer **views
|
|
231
|
+
dizininin üst dizinine** göre çözülür, yani varsayılan `views` ile
|
|
232
|
+
`"views/ozel.jsk"` → `<root>/views/ozel.jsk`.
|
|
228
233
|
|
|
229
|
-
Verilmezse sırayla: `views/layout.jsk`, `views/layout.ejs
|
|
230
|
-
|
|
234
|
+
Verilmezse sırayla: `views/layout.jsk`, `views/layout.ejs` (legacy), yoksa
|
|
235
|
+
framework'ün `src/templates/layout.jsk` varsayılanı. Ayrıntı:
|
|
236
|
+
[04-render-ve-sablonlar.md](./04-render-ve-sablonlar.md).
|
|
231
237
|
|
|
232
238
|
## `routes`
|
|
233
239
|
|
|
@@ -328,7 +334,7 @@ var.
|
|
|
328
334
|
| `trustProxy` | `boolean` | `true` | Express'in `trust proxy` ayarı. Ters proxy arkasında doğru protokol ve istemci IP'si için gerekli. |
|
|
329
335
|
| `cookieSecret` | `string \| null` | `null` | İmzalı cookie sırrı. Verilmezse `JSKELET_SECRET` okunur. |
|
|
330
336
|
| `csrf.enabled` | `boolean` | `true` | Origin/`Sec-Fetch-Site` kontrolü. |
|
|
331
|
-
| `csrf.token` | `boolean` | `false` | Çift gönderim token'ı katmanı. |
|
|
337
|
+
| `csrf.token` | `boolean` | `false` | Çift gönderim token'ı katmanı. Cookie oturumlu formlarda **açın**. |
|
|
332
338
|
| `csrf.allowedOrigins` | `string[]` | `[]` | Kendi host'umuzun yanında kabul edilen origin'ler. |
|
|
333
339
|
| `csrf.exclude` | `string[]` | `[]` | Kontrolden muaf yollar; `source` desen sözdizimi. |
|
|
334
340
|
| `csrf.cookieName` | `string` | `"csrf_token"` | Token cookie'sinin adı. |
|
|
@@ -336,14 +342,17 @@ var.
|
|
|
336
342
|
| `csrf.headerName` | `string` | `"x-csrf-token"` | Token'ın kabul edildiği başlık. |
|
|
337
343
|
|
|
338
344
|
`trustProxy` doğrudan internete açık bir sunucuda **kapatılmalı**: açıkken
|
|
339
|
-
istemci kendi `X-Forwarded-For`
|
|
340
|
-
|
|
345
|
+
istemci kendi `X-Forwarded-For` / `X-Forwarded-Proto` / Host başlığını
|
|
346
|
+
uydurabilir; rate limit, admin IP allowlist, Secure cookie ve cache `vary.host`
|
|
347
|
+
yanlış adresi görür. Ters proxy (nginx, Caddy, Cloudflare) arkasındaysa `true`
|
|
348
|
+
doğru varsayılandır.
|
|
341
349
|
|
|
342
350
|
CSRF kontrolü yalnızca çapraz site olduğu **belli** olan istekleri reddeder —
|
|
343
351
|
`Origin` uyuşmuyorsa ya da `Sec-Fetch-Site: cross-site` geldiyse. İkisi de yoksa
|
|
344
352
|
istek geçer, çünkü tarayıcılar çapraz origin bir POST'ta `Origin`'i her zaman
|
|
345
|
-
gönderirken webhook'lar hiç göndermez.
|
|
346
|
-
`csrf.
|
|
353
|
+
gönderirken webhook'lar hiç göndermez. Cookie ile oturum açan panel/form
|
|
354
|
+
uygulamalarında `csrf.token: true` + `csrfField()` ikinci katmandır; webhook
|
|
355
|
+
uçlarını `csrf.exclude` listesine yazın.
|
|
347
356
|
|
|
348
357
|
## `navigation`
|
|
349
358
|
|
|
@@ -540,7 +549,9 @@ icons: {
|
|
|
540
549
|
|
|
541
550
|
`false` verilirse görsel adımı hiç çalışmaz. Build adımı `sharp` gerektirir ve
|
|
542
551
|
watch turunda hiç çalışmaz. Remote açıksa `sharp` **runtime**'da da gerekir;
|
|
543
|
-
yoksa optimizer kaynak URL'ye 302 yönlendirir.
|
|
552
|
+
yoksa optimizer kaynak URL'ye 302 yönlendirir. Fetch, redirect'leri otomatik
|
|
553
|
+
takip etmez: her hop `allowHosts` ve private adres kontrolünden geçer.
|
|
554
|
+
Ayrıntı: [08-build.md](./08-build.md).
|
|
544
555
|
|
|
545
556
|
```js
|
|
546
557
|
images: {
|
|
@@ -573,6 +584,9 @@ clientEnv: ["PUBLIC_WS_URL", "PUBLIC_CDN_ORIGIN"]
|
|
|
573
584
|
```
|
|
574
585
|
|
|
575
586
|
**Buraya gizli anahtar koymayın** — değerler bundle'da düz metin olarak durur.
|
|
587
|
+
İsimlerinde `SECRET`, `PASSWORD`, `TOKEN`, `API_KEY`, `PRIVATE` vb. geçen
|
|
588
|
+
anahtarlar build sırasında **reddeder** (`PUBLIC` / `PUBLISHABLE` içerenler
|
|
589
|
+
muaf).
|
|
576
590
|
|
|
577
591
|
## `headers()`
|
|
578
592
|
|
|
@@ -581,7 +595,8 @@ clientEnv: ["PUBLIC_WS_URL", "PUBLIC_CDN_ORIGIN"]
|
|
|
581
595
|
|
|
582
596
|
Yol desenine göre yanıt başlıkları. Framework yalnızca statik dosyalara uzun
|
|
583
597
|
ömürlü cache yazar; bunun dışındaki her başlık (CSP, COOP, HSTS,
|
|
584
|
-
X-Frame-Options…) buradan gelir ve varsayılanların üstüne biner.
|
|
598
|
+
X-Frame-Options…) buradan gelir ve varsayılanların üstüne biner. Üretim
|
|
599
|
+
sitelerinde en azından aşağıdaki güvenlik başlıklarını tanımlayın.
|
|
585
600
|
|
|
586
601
|
Eşleşen **tüm** kurallar uygulanır (redirect'lerin aksine ilk eşleşmede
|
|
587
602
|
durulmaz), sırayla; aynı başlığı iki kural yazarsa sonraki kazanır.
|
|
@@ -596,11 +611,18 @@ async headers() {
|
|
|
596
611
|
source: "/:path*",
|
|
597
612
|
headers: [
|
|
598
613
|
{ key: "X-Frame-Options", value: "SAMEORIGIN" },
|
|
614
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
599
615
|
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
616
|
+
{
|
|
617
|
+
key: "Permissions-Policy",
|
|
618
|
+
value: "camera=(), microphone=(), geolocation=()",
|
|
619
|
+
},
|
|
600
620
|
{
|
|
601
621
|
key: "Content-Security-Policy",
|
|
602
|
-
value: "default-src 'self'; img-src 'self' https://cdn.ornek.com data
|
|
622
|
+
value: "default-src 'self'; img-src 'self' https://cdn.ornek.com data:; script-src 'self'",
|
|
603
623
|
},
|
|
624
|
+
// Yalnızca HTTPS terminasyonu sizin kontrolünüzdeyse:
|
|
625
|
+
// { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains" },
|
|
604
626
|
],
|
|
605
627
|
},
|
|
606
628
|
{
|
|
@@ -1081,7 +1103,7 @@ basılmaz.
|
|
|
1081
1103
|
| Değişken | Kim okur | Varsayılan | Anlamı |
|
|
1082
1104
|
| --- | --- | --- | --- |
|
|
1083
1105
|
| `NODE_ENV` | her yer | `production` (start/build), `development` (dev) | Dev overlay, EJS cache, manifest yeniden okuma, route hata davranışı ve prewarm varsayılanlarını belirler. `jskelet dev` bunu kendisi ayarlar — `cross-env` gerekmez. |
|
|
1084
|
-
| `PORT` | `startServer` | `3000` | Dinlenecek port |
|
|
1106
|
+
| `PORT` | `startServer` | `3000` | Dinlenecek port. Doluysa süreç başlamaz; `jskelet start|dev --murder` dinleyiciyi öldürür |
|
|
1085
1107
|
| `HOST` | `startServer` | `::` | Bağlanılacak arayüz. Varsayılan çift yığın dinler (IPv6 + IPv4); IPv6 yoksa `0.0.0.0`'a düşer |
|
|
1086
1108
|
| `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) |
|
|
1087
1109
|
| `DEV_TOKEN` | `devGate`, `prewarm` | — | Ayarlıysa token taşımayan her isteğe 404 döner. Isıtma token'ı çerez olarak taşır. [09](./09-dev-araclari.md) |
|