jskelet 0.5.5 → 0.6.1
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 +19 -15
- package/CHANGELOG.md +165 -15
- package/README.md +16 -21
- package/bin/jskelet.mjs +23 -9
- package/docs/01-baslangic.md +4 -3
- package/docs/02-mimari.md +10 -4
- package/docs/03-routing.md +14 -7
- package/docs/04-render-ve-sablonlar.md +60 -43
- package/docs/05-islands.md +12 -8
- package/docs/06-cache.md +18 -7
- package/docs/07-yapilandirma.md +69 -27
- package/docs/08-build.md +15 -9
- package/docs/09-dev-araclari.md +22 -8
- package/docs/10-dagitim.md +14 -13
- package/docs/11-tasima.md +51 -17
- package/docs/12-panel-ve-oturum.md +10 -4
- package/docs/README.md +10 -33
- package/docs/en/01-getting-started.md +4 -3
- package/docs/en/02-architecture.md +12 -6
- package/docs/en/03-routing.md +15 -8
- package/docs/en/04-rendering.md +71 -59
- package/docs/en/05-islands.md +13 -8
- package/docs/en/06-caching.md +21 -7
- package/docs/en/07-configuration.md +69 -29
- package/docs/en/08-build.md +16 -10
- package/docs/en/09-dev-tools.md +24 -8
- package/docs/en/10-deployment.md +14 -14
- package/docs/en/11-migration.md +51 -16
- package/docs/en/12-dashboards-and-sessions.md +9 -4
- package/docs/en/README.md +10 -35
- package/package.json +48 -13
- 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 +48 -5
- package/src/config/index.js +138 -27
- 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 +37 -10
- package/src/server/ejs-adapter.js +59 -0
- package/src/server/html-cache.js +178 -32
- package/src/server/image-optimizer.js +94 -26
- package/src/server/middleware/dev-gate.js +21 -8
- package/src/server/middleware/robots-txt.js +341 -0
- package/src/server/port-guard.js +255 -0
- package/src/server/prewarm.js +137 -51
- package/src/server/render.js +30 -10
- 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 +477 -0
- package/types/config/index.d.ts +304 -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 +207 -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/robots-txt.d.ts +33 -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 +131 -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;
|
|
@@ -26,8 +29,7 @@ zaten tartışılmış:
|
|
|
26
29
|
|
|
27
30
|
Belgeler iki dilde: Türkçesi `docs/`, İngilizcesi `docs/en/` altında ve
|
|
28
31
|
dosyalar birebir eşlenik. Bir belgeyi değiştirdiysen karşılığını da güncelle;
|
|
29
|
-
|
|
30
|
-
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.
|
|
31
33
|
|
|
32
34
|
## Doğrulama
|
|
33
35
|
|
|
@@ -96,16 +98,18 @@ parçalar ayrı ve `no-store` işaretli fragment uçlarında.
|
|
|
96
98
|
yalnızca `exports` haritasındaki belirteçler kullanılır (`jskelet`,
|
|
97
99
|
`jskelet/client`, `jskelet/html`, `jskelet/tags`).
|
|
98
100
|
|
|
99
|
-
##
|
|
101
|
+
## `.jsk` tuzakları
|
|
100
102
|
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
|
|
103
|
+
- İfade dilinde fonksiyon çağrısı, object/array literal ve atama yok — mantık
|
|
104
|
+
controller veya `views/components/*.js` içinde kalır. Layout’ta `asset()` /
|
|
105
|
+
`hasAsset()` için yerleşik `<Stylesheets />` / `<BodyScripts />` /
|
|
106
|
+
`<JsonLd />` kullan.
|
|
107
|
+
- `{#include "partials/x"}` aynı `data` nesnesini geçer; EJS’teki ikinci-argüman
|
|
108
|
+
locals yok — veriyi controller’da hazırla.
|
|
109
|
+
- `views/components/**` named export’ları PascalCase etiket olur; import yok.
|
|
110
|
+
- Kullanıcı verisi `{{ }}` ile kaçar; `{{{ }}}` yalnızca güvendiğin HTML için.
|
|
111
|
+
- Legacy EJS hâlâ varsa: `include` async’tir (`forEach` içinde `await` yok);
|
|
112
|
+
`<%= %>` / `<%- %>` ayrımına dikkat et; `ejs` opsiyonel peer olarak kurulmalı.
|
|
109
113
|
|
|
110
114
|
## Tailwind
|
|
111
115
|
|
|
@@ -118,7 +122,7 @@ sessizce çıktıdan düşer.
|
|
|
118
122
|
|
|
119
123
|
Framework'ün genel yüzeyini değiştirdiysen (`route()` imzası, hook adları,
|
|
120
124
|
config alanları, client API'si) `examples/minimal`, `examples/blog` ve
|
|
121
|
-
`examples/
|
|
125
|
+
`examples/dashboard`'i de güncelle. Örnekler belgelerdeki kod parçalarının kaynağı; kaymaları en hızlı
|
|
122
126
|
fark edilen yer orası.
|
|
123
127
|
|
|
124
128
|
## Windows notları
|
package/CHANGELOG.md
CHANGED
|
@@ -10,26 +10,175 @@ one is listed under a **Breaking** heading.
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
(
|
|
15
|
-
|
|
16
|
-
|
|
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.
|
|
17
31
|
|
|
18
32
|
### Fixed
|
|
19
33
|
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
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 /
|
|
95
|
+
`--murder` hint) instead of only `server exited (code 1)` when the child
|
|
96
|
+
dies during startup.
|
|
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).
|
|
107
|
+
|
|
108
|
+
### Breaking
|
|
109
|
+
|
|
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
|
|
116
|
+
`jskelet/layout/ejs` for the legacy file.
|
|
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.
|
|
23
125
|
|
|
24
126
|
### Changed
|
|
25
127
|
|
|
26
|
-
- Marketing
|
|
27
|
-
|
|
28
|
-
and
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
153
|
+
`POST /_jskelet/auth/handoff`.
|
|
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.
|
|
33
182
|
|
|
34
183
|
## [0.5.4] - 2026-09-18
|
|
35
184
|
|
|
@@ -408,7 +557,8 @@ Initial release.
|
|
|
408
557
|
- Documentation under `docs/` and three examples: `minimal`, `blog`,
|
|
409
558
|
`marketing`.
|
|
410
559
|
|
|
411
|
-
[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
|
|
412
562
|
[0.5.4]: https://github.com/ayberkenis/jskelet/compare/v0.5.3...v0.5.4
|
|
413
563
|
[0.5.3]: https://github.com/ayberkenis/jskelet/compare/v0.5.2...v0.5.3
|
|
414
564
|
[0.5.2]: https://github.com/ayberkenis/jskelet/compare/v0.5.1...v0.5.2
|
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
|
|
|
@@ -305,12 +307,13 @@ Anything reachable by a deeper path is internal and may change without notice.
|
|
|
305
307
|
## Deployment
|
|
306
308
|
|
|
307
309
|
The server is a plain Express 5 app, so anything that can run a Node process
|
|
308
|
-
works: a `Dockerfile` (see
|
|
309
|
-
a PaaS. Run `jskelet build` at image build time, put a
|
|
310
|
-
for TLS, and expose a health endpoint (the default
|
|
311
|
-
includes `/api/healthcheck`, so a route there is
|
|
312
|
-
Details, including cache sizing behind multiple
|
|
313
|
-
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) /
|
|
314
317
|
[docs/en/10-deployment.md](./docs/en/10-deployment.md).
|
|
315
318
|
|
|
316
319
|
## Documentation
|
|
@@ -341,7 +344,6 @@ apply to this repository.
|
|
|
341
344
|
```bash
|
|
342
345
|
npm --prefix examples/minimal install && npm --prefix examples/minimal run dev
|
|
343
346
|
npm --prefix examples/blog install && npm --prefix examples/blog run dev
|
|
344
|
-
npm --prefix examples/marketing install && npm --prefix examples/marketing run dev
|
|
345
347
|
npm --prefix examples/dashboard install && npm --prefix examples/dashboard run dev
|
|
346
348
|
```
|
|
347
349
|
|
|
@@ -350,13 +352,6 @@ npm --prefix examples/dashboard install && npm --prefix examples/dashboard run d
|
|
|
350
352
|
- **`examples/blog`** — dynamic routes, tag pages, every config section,
|
|
351
353
|
fragment-loaded tabs, a form, prewarm, RSS and sitemap, four islands. It
|
|
352
354
|
intentionally touches every surface of the framework.
|
|
353
|
-
- **`examples/marketing`** — the framework's own marketing site: comparison
|
|
354
|
-
table, changelog and download pages, long TTLs, prewarm covering every page.
|
|
355
|
-
The byte counts on the page are measured from that site's own build output, the
|
|
356
|
-
version details are read from the installed package, and the latency numbers
|
|
357
|
-
are measured in the browser; there are no invented benchmarks. It is also
|
|
358
|
-
bilingual — English at the root, Turkish under `/tr` — which shows how to build
|
|
359
|
-
a multi-language site on a framework that ships no i18n of its own.
|
|
360
355
|
- **`examples/dashboard`** — the opposite axis: per-visitor pages. A signed
|
|
361
356
|
cookie session, a `private: true` page that never enters the HTML cache, a
|
|
362
357
|
paginated table fragment, a CSRF-protected form that still works without
|
package/bin/jskelet.mjs
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
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
|
@@ -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
|
|
@@ -51,7 +52,7 @@ JSkelet bu gözlemi mimarinin merkezine alır:
|
|
|
51
52
|
│ └─ withHtmlCache TTL + stale-while-revalidate
|
|
52
53
|
│ └─ withUpstreamTracking
|
|
53
54
|
│ └─ withRequestCache
|
|
54
|
-
│ └─ controller → renderPage → EJS
|
|
55
|
+
│ └─ controller → renderPage → .jsk (veya legacy EJS)
|
|
55
56
|
├─ 404 → hooks.notFound()
|
|
56
57
|
└─ hata yönetimi redirect/notFound + 500 fallback
|
|
57
58
|
```
|
|
@@ -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).
|
|
@@ -254,8 +259,9 @@ teşhisi zor sorunlara dönüşüyor.
|
|
|
254
259
|
|
|
255
260
|
## Neden bu bağımlılık listesi
|
|
256
261
|
|
|
257
|
-
Çalışma zamanı bağımlılıkları
|
|
258
|
-
`tailwind-merge`.
|
|
262
|
+
Çalışma zamanı bağımlılıkları üçtür: `express`, `esbuild`,
|
|
263
|
+
`tailwind-merge`. `ejs` yalnızca legacy `.ejs` şablonları için opsiyonel peer'dır.
|
|
264
|
+
Geri kalan her şey (Tailwind, PostCSS, lightningcss, sharp,
|
|
259
265
|
Phosphor ikonları) **opsiyonel peer bağımlılığıdır** ve yoksa ilgili build adımı
|
|
260
266
|
atlanır.
|
|
261
267
|
|
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(
|
|
@@ -210,7 +212,7 @@ Controller `async (ctx) => sayfa` biçimindedir ve şu alanları döndürebilir:
|
|
|
210
212
|
|
|
211
213
|
| Alan | Tip | Varsayılan | Anlamı |
|
|
212
214
|
| --- | --- | --- | --- |
|
|
213
|
-
| `view` | `string` | — | `views/` altındaki şablon yolu, uzantısız: `"pages/home"` → `views/pages/home.ejs
|
|
215
|
+
| `view` | `string` | — | `views/` altındaki şablon yolu, uzantısız: `"pages/home"` → `views/pages/home.jsk` (yoksa legacy `.ejs`). |
|
|
214
216
|
| `data` | `object` | `{}` | Şablona local olarak geçen veriler. |
|
|
215
217
|
| `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
218
|
| `status` | `number` | `200` | HTTP durum kodu. Yalnızca 200 önbelleğe yazılır. |
|
|
@@ -326,12 +328,17 @@ hata yöneticisi devreye girer, hatayı loglar ve framework'ün kendi hata sayfa
|
|
|
326
328
|
`Cache-Control: no-store` ile döner. Durum kodu hatanın `statusCode` (ya da
|
|
327
329
|
`status`) alanından okunur; 400–599 aralığında değilse 500 kullanılır.
|
|
328
330
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
331
|
+
**Development** (`NODE_ENV=development`, yani `jskelet dev`): 5xx yanıtlarında
|
|
332
|
+
gömülü 500 sayfası ve `hooks.error()` atlanır; mesaj, yığın izi ve varsa
|
|
333
|
+
`cause` zinciri içeren bir teşhis sayfası döner. 4xx (404 vb.) development'ta
|
|
334
|
+
da her zamanki gibi durum sayfasıdır.
|
|
333
335
|
|
|
334
|
-
|
|
336
|
+
**Production**: framework'ün sayfası bilinçli olarak yalın — durum kodu, tek
|
|
337
|
+
satır başlık ve tek satır açıklama. Marka adı, gezinme ya da hata ayrıntısı
|
|
338
|
+
taşımaz; sunucunun içi ziyaretçiye açılmaz. Dil `brand.lang`ten gelir (`tr` ve
|
|
339
|
+
`en` hazır, diğerleri `en`e düşer).
|
|
340
|
+
|
|
341
|
+
Kendi sayfanı vermek için `hooks.error()` (yalnızca production / 4xx):
|
|
335
342
|
|
|
336
343
|
```js
|
|
337
344
|
// jskelet.config.mjs
|