jskelet 0.5.4 → 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 +387 -385
- 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 +53 -25
- package/docs/08-build.md +40 -18
- 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 +55 -27
- package/docs/en/08-build.md +43 -21
- 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 +152 -18
- 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 +31 -3
- 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
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { DEFAULT_ADMIN, DEFAULT_CLOUDFLARE, DEFAULT_UPSTREAM_LIMIT } from "./defaults.js";
|
|
2
|
+
/** Framework paketinin kökü — kendi şablonlarına ve varlıklarına erişir. */
|
|
3
|
+
export declare const FRAMEWORK_ROOT: string;
|
|
4
|
+
export type Eagerness = "conservative" | "moderate" | "eager";
|
|
5
|
+
export type NavigationConfig = {
|
|
6
|
+
prefetch: false | Eagerness;
|
|
7
|
+
prerender: false | Eagerness;
|
|
8
|
+
viewTransition: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Spekülasyon dışı bırakılan href desenleri.
|
|
11
|
+
*/
|
|
12
|
+
exclude: string[];
|
|
13
|
+
};
|
|
14
|
+
export type RedisConfig = {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
url: string | null;
|
|
17
|
+
namespace: string;
|
|
18
|
+
keyPrefix: string;
|
|
19
|
+
/**
|
|
20
|
+
* HTML gövdeleri paylaşılsın mı.
|
|
21
|
+
*/
|
|
22
|
+
html: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Veri önbelleği paylaşılsın mı.
|
|
25
|
+
*/
|
|
26
|
+
data: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Sıkıştırılmış gövdeler de paylaşılsın mı.
|
|
29
|
+
*/
|
|
30
|
+
storeEncoded: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* pub/sub invalidation yayını.
|
|
33
|
+
*/
|
|
34
|
+
events: boolean;
|
|
35
|
+
commandTimeoutMs: number;
|
|
36
|
+
};
|
|
37
|
+
export type LogKind = "http" | "event" | "error";
|
|
38
|
+
export type LogsConfig = {
|
|
39
|
+
/**
|
|
40
|
+
* Runtime http/event/error satırları stdout'a
|
|
41
|
+
* basılsın mı (banner/build satırları etkilenmez).
|
|
42
|
+
*/
|
|
43
|
+
console: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Sink'lere giden kayıt türleri.
|
|
46
|
+
*/
|
|
47
|
+
kinds: LogKind[];
|
|
48
|
+
file: {
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
dir: string;
|
|
51
|
+
rotate: "daily";
|
|
52
|
+
};
|
|
53
|
+
s3: {
|
|
54
|
+
enabled: boolean;
|
|
55
|
+
bucket: string | null;
|
|
56
|
+
prefix: string;
|
|
57
|
+
region: string | null;
|
|
58
|
+
endpoint: string | null;
|
|
59
|
+
flushIntervalMs: number;
|
|
60
|
+
maxBatch: number;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export type CompiledPattern = import('./pattern.js').CompiledPattern;
|
|
64
|
+
export type ResolvedConfig = {
|
|
65
|
+
/**
|
|
66
|
+
* Proje kökü (mutlak).
|
|
67
|
+
*/
|
|
68
|
+
root: string;
|
|
69
|
+
/**
|
|
70
|
+
* Config dosyası okundu mu.
|
|
71
|
+
*/
|
|
72
|
+
loaded: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Mutlak dizin yolları.
|
|
75
|
+
*/
|
|
76
|
+
dirs: Record<string, string>;
|
|
77
|
+
headers: {
|
|
78
|
+
pattern: CompiledPattern;
|
|
79
|
+
headers: {
|
|
80
|
+
key: string;
|
|
81
|
+
value: string;
|
|
82
|
+
}[];
|
|
83
|
+
}[];
|
|
84
|
+
redirects: {
|
|
85
|
+
pattern: CompiledPattern;
|
|
86
|
+
destination: string;
|
|
87
|
+
statusCode: number;
|
|
88
|
+
}[];
|
|
89
|
+
rewrites: {
|
|
90
|
+
phase: "beforeFiles" | "afterFiles";
|
|
91
|
+
pattern: CompiledPattern;
|
|
92
|
+
destination: string;
|
|
93
|
+
}[];
|
|
94
|
+
html: {
|
|
95
|
+
pattern: CompiledPattern;
|
|
96
|
+
seconds: number;
|
|
97
|
+
}[];
|
|
98
|
+
/**
|
|
99
|
+
* Yol deseni başına, HTML cache anahtarına girmesine izin verilen query
|
|
100
|
+
* parametreleri. Eşleşen kural yoksa query'li istek cache'lenmez.
|
|
101
|
+
*/
|
|
102
|
+
cacheQuery: {
|
|
103
|
+
pattern: CompiledPattern;
|
|
104
|
+
allow: true | string[];
|
|
105
|
+
}[];
|
|
106
|
+
/**
|
|
107
|
+
* Anahtara eklenen sabit parçalar (query allowlist'ten bağımsız). Host'tan
|
|
108
|
+
* locale üreten sitelerde `host: true` zorunlu.
|
|
109
|
+
*/
|
|
110
|
+
cacheVary: {
|
|
111
|
+
host: boolean;
|
|
112
|
+
headers: string[];
|
|
113
|
+
fn: ((req: import('express').Request) => string | null | undefined) | null;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* HTML önbelleğinin girdi sınırı.
|
|
117
|
+
*/
|
|
118
|
+
htmlMaxEntries: number;
|
|
119
|
+
/**
|
|
120
|
+
* Upstream veri önbelleği ayarları.
|
|
121
|
+
*/
|
|
122
|
+
data: Record<string, unknown>;
|
|
123
|
+
/**
|
|
124
|
+
* `fetch` sarılıp geçici hatalar otomatik bildirilsin mi.
|
|
125
|
+
*/
|
|
126
|
+
trackUpstream: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Render'ın okuduğu veri anahtarları kaydedilsin mi.
|
|
129
|
+
*/
|
|
130
|
+
trackDependencies: boolean;
|
|
131
|
+
transientRetry: {
|
|
132
|
+
attempts: number;
|
|
133
|
+
delayMs: number;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Opsiyonel Redis ikinci kademesi.
|
|
137
|
+
*/
|
|
138
|
+
redis: RedisConfig;
|
|
139
|
+
/**
|
|
140
|
+
* Upstream hız freni.
|
|
141
|
+
*/
|
|
142
|
+
upstream: typeof DEFAULT_UPSTREAM_LIMIT;
|
|
143
|
+
/**
|
|
144
|
+
* Kalıcı log sink'leri (dosya + S3).
|
|
145
|
+
*/
|
|
146
|
+
logs: LogsConfig;
|
|
147
|
+
/**
|
|
148
|
+
* Framework yönetim paneli.
|
|
149
|
+
*/
|
|
150
|
+
admin: typeof DEFAULT_ADMIN;
|
|
151
|
+
/**
|
|
152
|
+
* Cloudflare cache yüzeyi.
|
|
153
|
+
*/
|
|
154
|
+
cloudflare: typeof DEFAULT_CLOUDFLARE;
|
|
155
|
+
prewarm: Record<string, unknown>;
|
|
156
|
+
prewarmPriority: {
|
|
157
|
+
source: string;
|
|
158
|
+
test: (pathname: string) => boolean;
|
|
159
|
+
}[];
|
|
160
|
+
brand: Record<string, unknown>;
|
|
161
|
+
auth: {
|
|
162
|
+
crossSubdomainHandoff: boolean | Record<string, unknown>;
|
|
163
|
+
};
|
|
164
|
+
hooks: Record<string, Function>;
|
|
165
|
+
/**
|
|
166
|
+
* Layout `.ejs` dosyasının mutlak yolu.
|
|
167
|
+
*/
|
|
168
|
+
layout: string;
|
|
169
|
+
/**
|
|
170
|
+
* Açık route modülü listesi.
|
|
171
|
+
*/
|
|
172
|
+
routes: string[] | null;
|
|
173
|
+
/**
|
|
174
|
+
* URL'ler `/` ile bitsin mi (Next `trailingSlash`).
|
|
175
|
+
*/
|
|
176
|
+
trailingSlash: boolean;
|
|
177
|
+
static: {
|
|
178
|
+
extensions: Set<string>;
|
|
179
|
+
prefixes: string[];
|
|
180
|
+
};
|
|
181
|
+
devGateBypass: string[];
|
|
182
|
+
preconnect: string[];
|
|
183
|
+
navigation: NavigationConfig;
|
|
184
|
+
security: SecurityConfig;
|
|
185
|
+
prewarmSkip: string[];
|
|
186
|
+
/**
|
|
187
|
+
* Dev sunucusunun izlediği ek dizinler.
|
|
188
|
+
*/
|
|
189
|
+
watch: string[];
|
|
190
|
+
fonts: {
|
|
191
|
+
family: string;
|
|
192
|
+
slug?: string;
|
|
193
|
+
weights: number[];
|
|
194
|
+
}[];
|
|
195
|
+
icons: {
|
|
196
|
+
scan?: string[];
|
|
197
|
+
dir: string;
|
|
198
|
+
} | false;
|
|
199
|
+
images: ImagesConfig | false;
|
|
200
|
+
/**
|
|
201
|
+
* Client bundle'a gömülecek env anahtarları.
|
|
202
|
+
*/
|
|
203
|
+
clientEnv: string[];
|
|
204
|
+
};
|
|
205
|
+
export type ImagesRemoteConfig = {
|
|
206
|
+
enabled: boolean;
|
|
207
|
+
allowHosts: string[];
|
|
208
|
+
path: string;
|
|
209
|
+
maxWidth: number;
|
|
210
|
+
cacheMaxAge: number;
|
|
211
|
+
fetchTimeoutMs: number;
|
|
212
|
+
maxBytes: number;
|
|
213
|
+
};
|
|
214
|
+
export type ImagesConfig = {
|
|
215
|
+
widths: number[];
|
|
216
|
+
quality: number;
|
|
217
|
+
skip: string[];
|
|
218
|
+
remote: ImagesRemoteConfig | false;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* `bucket`, `JSKELET_LOG_BUCKET` veya `JSKELET_S3_BUCKET` değeri
|
|
222
|
+
* `ayberkenis/jskelet/logs` gibi bir yol olabilir: ilk segment bucket adı,
|
|
223
|
+
* kalanı nesne öneki. Böylece tek env ile hem kova hem klasör verilmiş olur.
|
|
224
|
+
*
|
|
225
|
+
* @param {string | null} value
|
|
226
|
+
* @returns {{ bucket: string | null, prefix: string | null }}
|
|
227
|
+
* `prefix` null → yol öneki taşımıyor; config/varsayılan kalsın.
|
|
228
|
+
*/
|
|
229
|
+
export declare function splitS3BucketPath(value: string | null): {
|
|
230
|
+
bucket: string | null;
|
|
231
|
+
prefix: string | null;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* @returns {{ accessKeyId: string, secretAccessKey: string,
|
|
235
|
+
* sessionToken: string | null } | null}
|
|
236
|
+
*/
|
|
237
|
+
export declare function readS3CredentialsFromEnv(): {
|
|
238
|
+
accessKeyId: string;
|
|
239
|
+
secretAccessKey: string;
|
|
240
|
+
sessionToken: string | null;
|
|
241
|
+
} | null;
|
|
242
|
+
/**
|
|
243
|
+
* Kalıcı log sink'leri. Bozuk bir `kinds` listesi siteyi düşürmemeli —
|
|
244
|
+
* bilinmeyen girdiler atılır; hiç geçerli tür kalmazsa varsayılana dönülür.
|
|
245
|
+
*
|
|
246
|
+
* @param {unknown} raw
|
|
247
|
+
* @returns {LogsConfig}
|
|
248
|
+
*/
|
|
249
|
+
export declare function normalizeLogs(raw: unknown): LogsConfig;
|
|
250
|
+
export type SecurityConfig = {
|
|
251
|
+
trustProxy: boolean;
|
|
252
|
+
cookieSecret: string | null;
|
|
253
|
+
csrf: {
|
|
254
|
+
enabled: boolean;
|
|
255
|
+
token: boolean;
|
|
256
|
+
allowedOrigins: string[];
|
|
257
|
+
exclude: CompiledPattern[];
|
|
258
|
+
cookieName: string;
|
|
259
|
+
fieldName: string;
|
|
260
|
+
headerName: string;
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Config'i okur, normalize eder ve modül durumuna yazar. Sunucu ve build
|
|
265
|
+
* süreçleri açılışta bir kez çağırır.
|
|
266
|
+
*
|
|
267
|
+
* Aynı süreçte ikinci çağrı önbelleğe düşer: `jskelet start` hem
|
|
268
|
+
* `ensure-build` hem `createApp` üzerinden çağırıyor ve config'i iki kez
|
|
269
|
+
* okuyup iki kez loglamanın hiçbir faydası yok. Yeniden okumak gerekiyorsa
|
|
270
|
+
* `force: true`.
|
|
271
|
+
*
|
|
272
|
+
* @param {{ root?: string, configFile?: string, force?: boolean }} [options]
|
|
273
|
+
* @returns {Promise<ResolvedConfig>}
|
|
274
|
+
*/
|
|
275
|
+
export declare function loadConfig(options?: {
|
|
276
|
+
root?: string;
|
|
277
|
+
configFile?: string;
|
|
278
|
+
force?: boolean;
|
|
279
|
+
}): Promise<ResolvedConfig>;
|
|
280
|
+
/**
|
|
281
|
+
* Çözümlenmiş config. `loadConfig()` çağrılmadan erişilirse boş bir proje
|
|
282
|
+
* kökü varsayımıyla çalışmak yerine hata verir: sessiz yanlış yol,
|
|
283
|
+
* "stylesheet neden yok" gibi teşhisi zor sorunlara dönüşüyor.
|
|
284
|
+
*
|
|
285
|
+
* @returns {ResolvedConfig}
|
|
286
|
+
*/
|
|
287
|
+
export declare function getConfig(): ResolvedConfig;
|
|
288
|
+
/**
|
|
289
|
+
* Uygulamanın tanımladığı hook'u çalıştırır; yoksa `fallback` döner.
|
|
290
|
+
* Hook'un hata vermesi sayfayı düşürmemeli — framework kendi varsayılanına
|
|
291
|
+
* geri döner ve uyarır.
|
|
292
|
+
*
|
|
293
|
+
* @template T
|
|
294
|
+
* @param {string} name
|
|
295
|
+
* @param {T} fallback
|
|
296
|
+
* @param {unknown[]} args
|
|
297
|
+
* @returns {Promise<T>}
|
|
298
|
+
*/
|
|
299
|
+
export declare function hook<T>(name: string, fallback: T, ...args: unknown[]): Promise<T>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `next.config` `source`/`destination` sözdiziminin küçük bir derleyicisi.
|
|
3
|
+
*
|
|
4
|
+
* Desteklenen biçimler:
|
|
5
|
+
* `/haber/:slug` → tek segment yakalar
|
|
6
|
+
* `/:path*` → sıfır veya daha fazla segment yakalar
|
|
7
|
+
* `/:path*.svg` → joker + sabit son ek (uzantı kuralları böyle yazılır)
|
|
8
|
+
* `/etiket-:slug` → segment ortasında parametre
|
|
9
|
+
*
|
|
10
|
+
* Yakalanan değerler `destination` içindeki aynı adlı `:param`'lara yazılır.
|
|
11
|
+
* Next'in tam `path-to-regexp` yüzeyi değil; config'te fiilen kullanılan alt
|
|
12
|
+
* küme bilinçli olarak seçildi ve tanınmayan bir sözdizimi sessizce literal
|
|
13
|
+
* kabul edilmez, uyarı üretir.
|
|
14
|
+
*/
|
|
15
|
+
export type CompiledPattern = {
|
|
16
|
+
regex: RegExp;
|
|
17
|
+
keys: string[];
|
|
18
|
+
source: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} source
|
|
22
|
+
* @returns {CompiledPattern | null}
|
|
23
|
+
*/
|
|
24
|
+
export declare function compilePattern(source: string): CompiledPattern | null;
|
|
25
|
+
/**
|
|
26
|
+
* @param {CompiledPattern} compiled
|
|
27
|
+
* @param {string} pathname
|
|
28
|
+
* @returns {Record<string, string> | null}
|
|
29
|
+
*/
|
|
30
|
+
export declare function matchPattern(compiled: CompiledPattern, pathname: string): Record<string, string> | null;
|
|
31
|
+
/**
|
|
32
|
+
* `destination` içindeki `:param` yer tutucularını doldurur.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} destination
|
|
35
|
+
* @param {Record<string, string>} params
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
export declare function fillDestination(destination: string, params: Record<string, string>): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `next/navigation` içindeki notFound/redirect kontrol akışının karşılığı.
|
|
3
|
+
* Derinlerdeki bir fonksiyon throw eder, Express error handler yakalar.
|
|
4
|
+
*/
|
|
5
|
+
export declare class NotFoundError extends Error {
|
|
6
|
+
statusCode: number;
|
|
7
|
+
constructor(message?: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class RedirectError extends Error {
|
|
10
|
+
location: string;
|
|
11
|
+
statusCode: 301 | 302 | 303 | 307 | 308;
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} location
|
|
14
|
+
* @param {301 | 302 | 303 | 307 | 308} [statusCode]
|
|
15
|
+
*/
|
|
16
|
+
constructor(location: string, statusCode?: 301 | 302 | 303 | 307 | 308);
|
|
17
|
+
}
|
|
18
|
+
/** @returns {never} */
|
|
19
|
+
export declare function notFound(): never;
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} location
|
|
22
|
+
* @returns {never}
|
|
23
|
+
*/
|
|
24
|
+
export declare function permanentRedirect(location: string): never;
|
|
25
|
+
/**
|
|
26
|
+
* @param {string} location
|
|
27
|
+
* @returns {never}
|
|
28
|
+
*/
|
|
29
|
+
export declare function redirect(location: string): never;
|
|
30
|
+
/**
|
|
31
|
+
* POST sonrası yönlendirme (303 See Other).
|
|
32
|
+
*
|
|
33
|
+
* `redirect()` 307 kullanır ve 307 **metodu korur**: bir POST handler'ından
|
|
34
|
+
* çağrıldığında tarayıcı hedefe yeniden POST eder. Form gönderiminden sonra
|
|
35
|
+
* sayfayı GET olarak açmak — yani geri tuşunun formu yeniden göndermediği
|
|
36
|
+
* klasik "post/redirect/get" akışı — 303 gerektiriyor.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} location
|
|
39
|
+
* @returns {never}
|
|
40
|
+
*/
|
|
41
|
+
export declare function seeOther(location: string): never;
|
|
42
|
+
/** @param {unknown} error */
|
|
43
|
+
export declare function isNotFoundError(error: unknown): error is NotFoundError;
|
|
44
|
+
/** @param {unknown} error */
|
|
45
|
+
export declare function isRedirectError(error: unknown): error is RedirectError;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `jskelet/cookies` paket girişi — imzalı cookie + paylaşımlı Domain yüzeyi.
|
|
3
|
+
*/
|
|
4
|
+
export { clearCookie, getSignedCookie, isValidCookieName, parseCookies, randomToken, safeEqual, serializeCookie, setCookie, setSignedCookie, } from "./cookies.js";
|
|
5
|
+
export { clearSharedCookie, requestIsHttps, resolveSharedCookieDomain, SHARED_COOKIE_WARN_BYTES, writeSharedCookie, } from "./shared-cookie.js";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sabit zamanlı karşılaştırma: imza doğrulamasında erken çıkış, saldırganın
|
|
3
|
+
* baytları tek tek tahmin etmesine kapı aralar.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} a
|
|
6
|
+
* @param {string} b
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/
|
|
9
|
+
export declare function safeEqual(a: string, b: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* `Cookie` başlığını ayrıştırır.
|
|
12
|
+
*
|
|
13
|
+
* Okuma çıktının kullanıcıya bağlı olduğunu bildirir: bu sayfa artık public
|
|
14
|
+
* HTML cache'ine yazılamaz.
|
|
15
|
+
*
|
|
16
|
+
* @param {import('http').IncomingMessage} req
|
|
17
|
+
* @returns {Record<string, string>}
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseCookies(req: import('http').IncomingMessage): Record<string, string>;
|
|
20
|
+
export type CookieOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* Varsayılan `/`.
|
|
23
|
+
*/
|
|
24
|
+
path?: string;
|
|
25
|
+
domain?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Saniye.
|
|
28
|
+
*/
|
|
29
|
+
maxAge?: number;
|
|
30
|
+
expires?: Date;
|
|
31
|
+
/**
|
|
32
|
+
* Varsayılan `true`.
|
|
33
|
+
*/
|
|
34
|
+
httpOnly?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Varsayılan: development dışında `true`.
|
|
37
|
+
* `writeSharedCookie` protokole bakarak ezer (`https` → Secure).
|
|
38
|
+
*/
|
|
39
|
+
secure?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Varsayılan `Lax`.
|
|
42
|
+
*/
|
|
43
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {object} CookieOptions
|
|
47
|
+
* @property {string} [path] Varsayılan `/`.
|
|
48
|
+
* @property {string} [domain]
|
|
49
|
+
* @property {number} [maxAge] Saniye.
|
|
50
|
+
* @property {Date} [expires]
|
|
51
|
+
* @property {boolean} [httpOnly] Varsayılan `true`.
|
|
52
|
+
* @property {boolean} [secure] Varsayılan: development dışında `true`.
|
|
53
|
+
* `writeSharedCookie` protokole bakarak ezer (`https` → Secure).
|
|
54
|
+
* @property {"Strict" | "Lax" | "None"} [sameSite] Varsayılan `Lax`.
|
|
55
|
+
*/
|
|
56
|
+
/**
|
|
57
|
+
* RFC 6265 cookie-name (token). `;`, boşluk, CRLF gibi karakterler
|
|
58
|
+
* Set-Cookie enjeksiyonuna yol açardı — reddedilir.
|
|
59
|
+
*
|
|
60
|
+
* @param {unknown} name
|
|
61
|
+
* @returns {boolean}
|
|
62
|
+
*/
|
|
63
|
+
export declare function isValidCookieName(name: unknown): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Varsayılanlar bilinçli olarak kısıtlayıcı: `HttpOnly` ile JS okuyamaz,
|
|
66
|
+
* `SameSite=Lax` ile çapraz site POST'larında gönderilmez (CSRF'nin büyük
|
|
67
|
+
* kısmını kapatan tek satır), `Secure` üretimde açık.
|
|
68
|
+
*
|
|
69
|
+
* @param {string} name
|
|
70
|
+
* @param {string} value
|
|
71
|
+
* @param {CookieOptions} [options]
|
|
72
|
+
* @returns {string}
|
|
73
|
+
*/
|
|
74
|
+
export declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
|
|
75
|
+
/**
|
|
76
|
+
* @param {import('http').ServerResponse} res
|
|
77
|
+
* @param {string} name
|
|
78
|
+
* @param {string} value
|
|
79
|
+
* @param {CookieOptions} [options]
|
|
80
|
+
*/
|
|
81
|
+
export declare function setCookie(res: import('http').ServerResponse, name: string, value: string, options?: CookieOptions): void;
|
|
82
|
+
/**
|
|
83
|
+
* @param {import('http').ServerResponse} res
|
|
84
|
+
* @param {string} name
|
|
85
|
+
* @param {CookieOptions} [options]
|
|
86
|
+
*/
|
|
87
|
+
export declare function clearCookie(res: import('http').ServerResponse, name: string, options?: CookieOptions): void;
|
|
88
|
+
/**
|
|
89
|
+
* İmzalı cookie yazar. Değer okunabilir kalır (şifreleme değil, imza);
|
|
90
|
+
* gizli kalması gereken veriyi cookie'ye koymayın, kimliğini koyun.
|
|
91
|
+
*
|
|
92
|
+
* @param {import('http').ServerResponse} res
|
|
93
|
+
* @param {string} name
|
|
94
|
+
* @param {string} value
|
|
95
|
+
* @param {CookieOptions} [options]
|
|
96
|
+
*/
|
|
97
|
+
export declare function setSignedCookie(res: import('http').ServerResponse, name: string, value: string, options?: CookieOptions): void;
|
|
98
|
+
/**
|
|
99
|
+
* İmzalı cookie okur. İmza uymuyorsa `null` — bozuk imza, yok sayılmalı,
|
|
100
|
+
* "belki geçerlidir" diye kullanılmamalı.
|
|
101
|
+
*
|
|
102
|
+
* @param {import('http').IncomingMessage} req
|
|
103
|
+
* @param {string} name
|
|
104
|
+
* @returns {string | null}
|
|
105
|
+
*/
|
|
106
|
+
export declare function getSignedCookie(req: import('http').IncomingMessage, name: string): string | null;
|
|
107
|
+
/**
|
|
108
|
+
* Kriptografik rastgele token. CSRF token'ı ve oturum kimliği için.
|
|
109
|
+
*
|
|
110
|
+
* @param {number} [bytes]
|
|
111
|
+
* @returns {string}
|
|
112
|
+
*/
|
|
113
|
+
export declare function randomToken(bytes?: number): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* İsteği bir memo bağlamı içinde çalıştırır.
|
|
3
|
+
* @param {() => T} run
|
|
4
|
+
* @returns {T}
|
|
5
|
+
* @template T
|
|
6
|
+
*/
|
|
7
|
+
export declare function withRequestCache<T>(run: () => T): T;
|
|
8
|
+
/**
|
|
9
|
+
* @param {F} fn
|
|
10
|
+
* @returns {F}
|
|
11
|
+
* @template {(...args: any[]) => any} F
|
|
12
|
+
*/
|
|
13
|
+
export declare function cache<F extends (...args: any[]) => any>(fn: F): F;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type RequestContext = {
|
|
2
|
+
/**
|
|
3
|
+
* Route `private: true` ile mi kaydedildi.
|
|
4
|
+
*/
|
|
5
|
+
private: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Kimliğe bağlı bir veri okundu mu.
|
|
8
|
+
*/
|
|
9
|
+
tainted: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Hangi erişimler işaretledi (teşhis için).
|
|
12
|
+
*/
|
|
13
|
+
taintReasons: string[];
|
|
14
|
+
csrfToken: string | null;
|
|
15
|
+
res: import('express').Response | null;
|
|
16
|
+
/**
|
|
17
|
+
* Devtools: bu isteğin sayfa yolu (SSR
|
|
18
|
+
* sırasında upstream hatasına "hangi sayfa" bağlamak için).
|
|
19
|
+
*/
|
|
20
|
+
pathname: string | null;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* @param {{ private?: boolean, res?: import('express').Response, pathname?: string | null }} [initial]
|
|
24
|
+
* @returns {RequestContext}
|
|
25
|
+
*/
|
|
26
|
+
export declare function createRequestContext(initial?: {
|
|
27
|
+
private?: boolean;
|
|
28
|
+
res?: import('express').Response;
|
|
29
|
+
pathname?: string | null;
|
|
30
|
+
}): RequestContext;
|
|
31
|
+
/**
|
|
32
|
+
* İsteği verilen bağlam içinde çalıştırır.
|
|
33
|
+
*
|
|
34
|
+
* @template T
|
|
35
|
+
* @param {RequestContext} context
|
|
36
|
+
* @param {() => T} run
|
|
37
|
+
* @returns {T}
|
|
38
|
+
*/
|
|
39
|
+
export declare function withRequestContext<T>(context: RequestContext, run: () => T): T;
|
|
40
|
+
/**
|
|
41
|
+
* @returns {RequestContext | undefined}
|
|
42
|
+
*/
|
|
43
|
+
export declare function getRequestContext(): RequestContext | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Çıktının kullanıcıya bağlı olduğunu bildirir. Bağlam yoksa (script, build,
|
|
46
|
+
* fragment dışı kullanım) sessizce yok sayılır.
|
|
47
|
+
*
|
|
48
|
+
* @param {string} reason Teşhis mesajında görünecek erişim adı.
|
|
49
|
+
*/
|
|
50
|
+
export declare function markTainted(reason: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Controller'a giden `req`'i kimliğe dokunan erişimleri işaretleyen bir Proxy
|
|
53
|
+
* ile sarar.
|
|
54
|
+
*
|
|
55
|
+
* Neden gerekli: HTML cache anahtarı yalnızca yol + query. Cookie okuyan bir
|
|
56
|
+
* controller cache'lenebilir bir route'a bağlanmışsa bir kullanıcının HTML'i
|
|
57
|
+
* bir başkasına servis edilir ve bu hiçbir yerde hata olarak görünmez.
|
|
58
|
+
* İşaretleme, sessiz sızıntıyı gürültülü bir uyarıya çeviriyor.
|
|
59
|
+
*
|
|
60
|
+
* Kapsam bilinçli olarak dar: yalnızca *okuma* yakalanır, yazma ve metot
|
|
61
|
+
* çağrıları hedefe dokunulmadan geçer. Proxy'nin prototipi korunduğu için
|
|
62
|
+
* `req instanceof IncomingMessage` gibi kontroller etkilenmez.
|
|
63
|
+
*
|
|
64
|
+
* @param {import('express').Request} req
|
|
65
|
+
* @returns {import('express').Request}
|
|
66
|
+
*/
|
|
67
|
+
export declare function guardRequest(req: import('express').Request): import('express').Request;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export { SHARED_COOKIE_WARN_BYTES, resolveSharedCookieDomain, stripHostPort, } from "../shared/cookie-domain.js";
|
|
2
|
+
/**
|
|
3
|
+
* @param {{ secure?: boolean, protocol?: string,
|
|
4
|
+
* headers?: Record<string, unknown>, get?: (name: string) => string | undefined }} [req]
|
|
5
|
+
* @returns {boolean}
|
|
6
|
+
*/
|
|
7
|
+
export declare function requestIsHttps(req?: {
|
|
8
|
+
secure?: boolean;
|
|
9
|
+
protocol?: string;
|
|
10
|
+
headers?: Record<string, unknown>;
|
|
11
|
+
get?: (name: string) => string | undefined;
|
|
12
|
+
}): boolean;
|
|
13
|
+
export type CookieOptions = import('./cookies.js').CookieOptions;
|
|
14
|
+
export type SharedCookieResult = {
|
|
15
|
+
/**
|
|
16
|
+
* Domain seçildi ve Set-Cookie yazıldı.
|
|
17
|
+
*/
|
|
18
|
+
ok: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Yazılan Domain ya da null.
|
|
21
|
+
*/
|
|
22
|
+
domain: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* ok değilse çağıran handoff denemeli.
|
|
25
|
+
*/
|
|
26
|
+
handoff: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Teşhis.
|
|
29
|
+
*/
|
|
30
|
+
reason?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {import('./cookies.js').CookieOptions} CookieOptions
|
|
34
|
+
*
|
|
35
|
+
* @typedef {object} SharedCookieResult
|
|
36
|
+
* @property {boolean} ok Domain seçildi ve Set-Cookie yazıldı.
|
|
37
|
+
* @property {string | null} domain Yazılan Domain ya da null.
|
|
38
|
+
* @property {boolean} handoff ok değilse çağıran handoff denemeli.
|
|
39
|
+
* @property {string} [reason] Teşhis.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Paylaşımlı Domain ile cookie yazar.
|
|
43
|
+
*
|
|
44
|
+
* @param {import('http').ServerResponse & { req?: import('http').IncomingMessage }} res
|
|
45
|
+
* @param {string} name
|
|
46
|
+
* @param {string} value Kısa session id — JWT değil.
|
|
47
|
+
* @param {CookieOptions & { req?: import('http').IncomingMessage, roots?: string[],
|
|
48
|
+
* host?: string }} [options]
|
|
49
|
+
* @returns {SharedCookieResult}
|
|
50
|
+
*/
|
|
51
|
+
export declare function writeSharedCookie(res: import('http').ServerResponse & {
|
|
52
|
+
req?: import('http').IncomingMessage;
|
|
53
|
+
}, name: string, value: string, options?: CookieOptions & {
|
|
54
|
+
req?: import('http').IncomingMessage;
|
|
55
|
+
roots?: string[];
|
|
56
|
+
host?: string;
|
|
57
|
+
}): SharedCookieResult;
|
|
58
|
+
/**
|
|
59
|
+
* Aynı Domain ile cookie siler.
|
|
60
|
+
*
|
|
61
|
+
* @param {import('http').ServerResponse & { req?: import('http').IncomingMessage }} res
|
|
62
|
+
* @param {string} name
|
|
63
|
+
* @param {CookieOptions & { req?: import('http').IncomingMessage, roots?: string[],
|
|
64
|
+
* host?: string }} [options]
|
|
65
|
+
* @returns {SharedCookieResult}
|
|
66
|
+
*/
|
|
67
|
+
export declare function clearSharedCookie(res: import('http').ServerResponse & {
|
|
68
|
+
req?: import('http').IncomingMessage;
|
|
69
|
+
}, name: string, options?: CookieOptions & {
|
|
70
|
+
req?: import('http').IncomingMessage;
|
|
71
|
+
roots?: string[];
|
|
72
|
+
host?: string;
|
|
73
|
+
}): SharedCookieResult;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSkelet sunucu tarafı genel API'si.
|
|
3
|
+
*
|
|
4
|
+
* `import { route, notFound } from "jskelet"` — route dosyaları ve
|
|
5
|
+
* controller'lar bu yüzeyi kullanır. Alt yollardan (`jskelet/server`)
|
|
6
|
+
* ithal etmek de mümkün; buradaki liste "kararlı" sayılan yüzeydir.
|
|
7
|
+
*/
|
|
8
|
+
export { route, fragment, renderPage, renderView, renderNotFound, } from "./server/render.js";
|
|
9
|
+
export { renderStatusPage, statusFromError } from "./server/status-page.js";
|
|
10
|
+
export { createApp, startServer } from "./server/create-app.js";
|
|
11
|
+
export { notFound, redirect, permanentRedirect, seeOther, isNotFoundError, isRedirectError, NotFoundError, RedirectError, } from "./http/control-flow.js";
|
|
12
|
+
export { cache, withRequestCache } from "./http/request-cache.js";
|
|
13
|
+
export { clearCookie, getSignedCookie, parseCookies, randomToken, safeEqual, serializeCookie, setCookie, setSignedCookie, } from "./http/cookies.js";
|
|
14
|
+
export { clearSharedCookie, requestIsHttps, resolveSharedCookieDomain, SHARED_COOKIE_WARN_BYTES, writeSharedCookie, } from "./http/shared-cookie.js";
|
|
15
|
+
export { reportUpstreamFailure } from "./server/upstream-tracking.js";
|
|
16
|
+
export { asset, hasAsset, optimizedImage, getSpriteIds } from "./server/assets.js";
|
|
17
|
+
export { remoteImageUrl, parseAllowedRemoteUrl } from "./server/image-optimizer.js";
|
|
18
|
+
export { ImageResponse, OG_SIZE, buildOgSvg, escapeXml, ogHandler, ogImage, sendOgImage, wrapText, } from "./server/og-image.js";
|
|
19
|
+
export { headHints } from "./server/head-hints.js";
|
|
20
|
+
export { renderHeadMeta } from "./server/metadata.js";
|
|
21
|
+
export { clearHtmlCache, dropHtmlCacheKey, getHtmlCacheEntries, getHtmlCacheSize, invalidateHtmlCache, withHtmlCache, } from "./server/html-cache.js";
|
|
22
|
+
export { clearDataCache, dataCache, dropDataCacheKey, getDataCacheEntries, getDataCacheSize, getDataCacheStats, withDataCache, } from "./server/data-cache.js";
|
|
23
|
+
export { getRedisDetails, getRedisStatus, inspectRedis } from "./server/redis.js";
|
|
24
|
+
export { cloudflareConfigured, fetchCacheAnalytics, fetchCloudflareOverview, fetchPathEdges, getCloudflareStatus, purgeCloudflare, toCloudflareUrls, } from "./server/cloudflare.js";
|
|
25
|
+
export { getUpstreamLimiterStatus } from "./server/upstream-limiter.js";
|
|
26
|
+
export { prewarm, prewarmProgress, extractSameOriginLinks, isOnVisitPrewarm } from "./server/prewarm.js";
|
|
27
|
+
export { createProxy } from "./server/middleware/upstream-proxy.js";
|
|
28
|
+
export { getConfig, loadConfig } from "./config/index.js";
|
|
29
|
+
export { attrs, cn, cx, esc, jsonScript } from "./views/helpers/html.js";
|
|
30
|
+
export { csrfField, icon, image, link, preloadImage } from "./views/helpers/tags.js";
|