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,82 @@
|
|
|
1
|
+
export type ExprNode = import('./expr.js').ExprNode;
|
|
2
|
+
export type TextNode = {
|
|
3
|
+
type: 'Text';
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
export type InterpNode = {
|
|
7
|
+
type: 'Interp';
|
|
8
|
+
expr: ExprNode;
|
|
9
|
+
raw: boolean;
|
|
10
|
+
index: number;
|
|
11
|
+
};
|
|
12
|
+
export type AttrNode = {
|
|
13
|
+
name: string;
|
|
14
|
+
value: string | null;
|
|
15
|
+
expr: ExprNode | null;
|
|
16
|
+
bound: boolean;
|
|
17
|
+
boolean: boolean;
|
|
18
|
+
index: number;
|
|
19
|
+
};
|
|
20
|
+
export type ElementNode = {
|
|
21
|
+
type: 'Element';
|
|
22
|
+
name: string;
|
|
23
|
+
attrs: AttrNode[];
|
|
24
|
+
children: AstNode[];
|
|
25
|
+
selfClosing: boolean;
|
|
26
|
+
index: number;
|
|
27
|
+
};
|
|
28
|
+
export type ComponentNode = {
|
|
29
|
+
type: 'Component';
|
|
30
|
+
name: string;
|
|
31
|
+
attrs: AttrNode[];
|
|
32
|
+
children: AstNode[];
|
|
33
|
+
selfClosing: boolean;
|
|
34
|
+
index: number;
|
|
35
|
+
};
|
|
36
|
+
export type IfNode = {
|
|
37
|
+
type: 'If';
|
|
38
|
+
test: ExprNode;
|
|
39
|
+
consequent: AstNode[];
|
|
40
|
+
alternate: AstNode[];
|
|
41
|
+
index: number;
|
|
42
|
+
};
|
|
43
|
+
export type EachNode = {
|
|
44
|
+
type: 'Each';
|
|
45
|
+
list: ExprNode;
|
|
46
|
+
item: string;
|
|
47
|
+
indexName: string | null;
|
|
48
|
+
children: AstNode[];
|
|
49
|
+
index: number;
|
|
50
|
+
};
|
|
51
|
+
export type IncludeNode = {
|
|
52
|
+
type: 'Include';
|
|
53
|
+
path: string;
|
|
54
|
+
index: number;
|
|
55
|
+
};
|
|
56
|
+
export type AstNode = TextNode | InterpNode | ElementNode | ComponentNode | IfNode | EachNode | IncludeNode;
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {import('./expr.js').ExprNode} ExprNode
|
|
59
|
+
* @typedef {{ type: 'Text', value: string }} TextNode
|
|
60
|
+
* @typedef {{ type: 'Interp', expr: ExprNode, raw: boolean, index: number }} InterpNode
|
|
61
|
+
* @typedef {{ name: string, value: string | null, expr: ExprNode | null, bound: boolean, boolean: boolean, index: number }} AttrNode
|
|
62
|
+
* @typedef {{ type: 'Element', name: string, attrs: AttrNode[], children: AstNode[], selfClosing: boolean, index: number }} ElementNode
|
|
63
|
+
* @typedef {{ type: 'Component', name: string, attrs: AttrNode[], children: AstNode[], selfClosing: boolean, index: number }} ComponentNode
|
|
64
|
+
* @typedef {{ type: 'If', test: ExprNode, consequent: AstNode[], alternate: AstNode[], index: number }} IfNode
|
|
65
|
+
* @typedef {{ type: 'Each', list: ExprNode, item: string, indexName: string | null, children: AstNode[], index: number }} EachNode
|
|
66
|
+
* @typedef {{ type: 'Include', path: string, index: number }} IncludeNode
|
|
67
|
+
* @typedef {TextNode | InterpNode | ElementNode | ComponentNode | IfNode | EachNode | IncludeNode} AstNode
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} source
|
|
71
|
+
* @param {{ file?: string }} [options]
|
|
72
|
+
* @returns {AstNode[]}
|
|
73
|
+
*/
|
|
74
|
+
export declare function parseTemplate(source: string, options?: {
|
|
75
|
+
file?: string;
|
|
76
|
+
}): AstNode[];
|
|
77
|
+
/**
|
|
78
|
+
* PascalCase bileşen mi?
|
|
79
|
+
* @param {string} name
|
|
80
|
+
* @returns {boolean}
|
|
81
|
+
*/
|
|
82
|
+
export declare function isComponentTag(name: string): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime'ın camelCase → PascalCase alias'ı ile aynı kural.
|
|
3
|
+
* @param {string} name
|
|
4
|
+
* @returns {string}
|
|
5
|
+
*/
|
|
6
|
+
export declare function toComponentTag(name: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* @param {{ root: string, dirs: Record<string, string> }} config
|
|
9
|
+
* @returns {string[]} Mutlak view kökleri (var olanlar).
|
|
10
|
+
*/
|
|
11
|
+
export declare function getViewRoots(config: {
|
|
12
|
+
root: string;
|
|
13
|
+
dirs: Record<string, string>;
|
|
14
|
+
}): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Bileşen dizinleri: her view kökü altındaki `components/`.
|
|
17
|
+
* @param {{ root: string, dirs: Record<string, string> }} config
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
export declare function getComponentDirs(config: {
|
|
21
|
+
root: string;
|
|
22
|
+
dirs: Record<string, string>;
|
|
23
|
+
}): string[];
|
|
24
|
+
/**
|
|
25
|
+
* @param {string[]} viewRoots
|
|
26
|
+
* @returns {Map<string, string>} viewId → mutlak `.jsk` yolu
|
|
27
|
+
*/
|
|
28
|
+
export declare function discoverJskFiles(viewRoots: string[]): Map<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* `components/foo-bar.jsk` → `FooBar`
|
|
31
|
+
* @param {string} viewId
|
|
32
|
+
* @returns {string | null}
|
|
33
|
+
*/
|
|
34
|
+
export declare function componentNameFromViewId(viewId: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Bilinen bileşen adları: JS named export'lar + derlenecek `.jsk` bileşenleri
|
|
37
|
+
* + yerleşik etiketler.
|
|
38
|
+
*
|
|
39
|
+
* JS tarafında dosya adı varsayılmaz; kaynak metinden `export` adları okunur.
|
|
40
|
+
* Aynı export (veya aynı PascalCase etiket) iki dosyada varsa derleme hatası.
|
|
41
|
+
*
|
|
42
|
+
* @param {string[]} componentDirs
|
|
43
|
+
* @param {Map<string, string>} jskFiles
|
|
44
|
+
* @returns {Set<string>}
|
|
45
|
+
*/
|
|
46
|
+
export declare function collectKnownComponents(componentDirs: string[], jskFiles: Map<string, string>): Set<string>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kaynak metinden named export adlarını çıkarır — modülü çalıştırmadan.
|
|
3
|
+
* Compile-time bilinen bileşen listesi için; `default` yok sayılır.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} source
|
|
7
|
+
* @returns {string[]}
|
|
8
|
+
*/
|
|
9
|
+
export declare function scanNamedExports(source: string): string[];
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework varsayılanları.
|
|
3
|
+
*
|
|
4
|
+
* Buradaki hiçbir değer domain bilgisi taşımaz: uygulamaya özel her şey
|
|
5
|
+
* `jskelet.config.mjs` üzerinden gelir. Varsayılanların ayrı dosyada olması,
|
|
6
|
+
* "framework ne yapıyor, uygulama ne ekliyor" ayrımını okunur tutar.
|
|
7
|
+
*/
|
|
8
|
+
/** Uzun süre cache'lenecek hash'li çıktı dizini. */
|
|
9
|
+
export declare const IMMUTABLE_CACHE = "public, max-age=31536000, immutable";
|
|
10
|
+
/**
|
|
11
|
+
* Proje kökündeki dizin adları. `jskelet.config.mjs` içinde `paths` ile
|
|
12
|
+
* tek tek ezilebilir.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DEFAULT_DIRS: {
|
|
15
|
+
/** Layout + sayfalar + bileşenler (klasik kök). */
|
|
16
|
+
views: string;
|
|
17
|
+
/** Feature-first dikey dilimler (`features/<name>/{server,views,client}`). */
|
|
18
|
+
features: string;
|
|
19
|
+
/** Özellikler arası paylaşılan server/views/client. */
|
|
20
|
+
shared: string;
|
|
21
|
+
/** Statik dosyalar; build çıktısı da buraya yazılır. */
|
|
22
|
+
public: string;
|
|
23
|
+
/** Island runtime ve entry'ler. */
|
|
24
|
+
client: string;
|
|
25
|
+
/** Route modülleri. */
|
|
26
|
+
routes: string;
|
|
27
|
+
/** Tailwind/PostCSS giriş dosyası. */
|
|
28
|
+
styles: string;
|
|
29
|
+
/** Build ara çıktıları (manifest, metafile, images, templates). */
|
|
30
|
+
generated: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Uzantı ve önek bazlı statik dosya tespiti. Bu listeye uyan yollara
|
|
34
|
+
* `IMMUTABLE_CACHE` yazılır.
|
|
35
|
+
*/
|
|
36
|
+
export declare const DEFAULT_STATIC: {
|
|
37
|
+
extensions: string[];
|
|
38
|
+
prefixes: string[];
|
|
39
|
+
};
|
|
40
|
+
/** Dev gate'in hiçbir koşulda kapatmadığı yollar. */
|
|
41
|
+
export declare const DEFAULT_DEV_GATE_BYPASS: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Klasik (liste tabanlı) prewarm ayarları. `onVisit` modu bunlarla birlikte
|
|
44
|
+
* kullanılamaz — ya açılış/`prewarmPaths` turu, ya ziyaret edilen sayfadaki
|
|
45
|
+
* linkleri ısıtma.
|
|
46
|
+
*/
|
|
47
|
+
export declare const DEFAULT_PREWARM: {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
max: number;
|
|
50
|
+
intervalSeconds: number;
|
|
51
|
+
/** Paralel ısıtma isteği; dev'de sunucu tek süreç olduğu için düşürülür. */
|
|
52
|
+
concurrency: number;
|
|
53
|
+
/** İki tur arasında beklenen süre: upstream'e ani yük binmesin. */
|
|
54
|
+
delayMs: number;
|
|
55
|
+
/**
|
|
56
|
+
* Saniyedeki en fazla ısıtma isteği. 0 → sınırsız (yalnızca `concurrency`
|
|
57
|
+
* frenler). Upstream'i kota sınırının altında tutmanın en doğrudan yolu bu:
|
|
58
|
+
* paralellik ne kadar yükselse de tur bu hızın üstüne çıkmaz.
|
|
59
|
+
*/
|
|
60
|
+
rps: number;
|
|
61
|
+
/**
|
|
62
|
+
* Tekrar turundan önce beklenen süre. Rate limit pencereleri saniye
|
|
63
|
+
* mertebesinde; hemen tekrar denemek aynı 429'u almak demek.
|
|
64
|
+
*/
|
|
65
|
+
retryDelayMs: number;
|
|
66
|
+
/**
|
|
67
|
+
* Liste `max`'tan uzunsa periyodik turlar kaldığı yerden devam eder.
|
|
68
|
+
* Böylece 10.000 yolluk bir site tek turda değil, turlar boyunca ısınır.
|
|
69
|
+
* `priority` eşleşen yollar her turda ısıtıldığı için rotasyon yalnızca
|
|
70
|
+
* kuyruğu dolaşır.
|
|
71
|
+
*/
|
|
72
|
+
rotate: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Isıtma sırasını belirleyen desenler. String (`/haber/:slug`) ya da
|
|
75
|
+
* `RegExp` kabul eder; önce yazılan önce ısınır.
|
|
76
|
+
* @type {(string | RegExp)[]}
|
|
77
|
+
*/
|
|
78
|
+
priority: (string | RegExp)[];
|
|
79
|
+
/**
|
|
80
|
+
* Klasik turda ısıtılacak origin listesi. Boşsa `http://127.0.0.1:<port>`.
|
|
81
|
+
* `cache().vary.host` açıkken locale host'ları buraya yazılmazsa yalnızca
|
|
82
|
+
* loopback anahtarı ısınır.
|
|
83
|
+
* @type {string[]}
|
|
84
|
+
*/
|
|
85
|
+
origins: string[];
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Ziyaret tabanlı ısıtma. Bir sayfa servis edilince HTML'deki aynı-origin
|
|
89
|
+
* linkler kuyruğa alınır; bir sonraki tıklama (veya başka ziyaretçi) çoğu
|
|
90
|
+
* zaman HIT görür. Klasik `prewarm` alanlarıyla karşılıklı dışlayıcıdır.
|
|
91
|
+
*/
|
|
92
|
+
export declare const DEFAULT_PREWARM_ON_VISIT: {
|
|
93
|
+
enabled: boolean;
|
|
94
|
+
/** Sayfa başına üstten alta en fazla kaç link kuyruğa alınır. */
|
|
95
|
+
perPage: number;
|
|
96
|
+
/**
|
|
97
|
+
* Paralel işçi; `null` → klasik prewarm ile aynı varsayılan
|
|
98
|
+
* (prod 4 / dev 1) `startPrewarm` içinde çözülür.
|
|
99
|
+
* @type {number | null}
|
|
100
|
+
*/
|
|
101
|
+
concurrency: number | null;
|
|
102
|
+
/**
|
|
103
|
+
* Saniyedeki istek tavanı; `null` → klasik ile aynı (prod 0 / dev 4).
|
|
104
|
+
* @type {number | null}
|
|
105
|
+
*/
|
|
106
|
+
rps: number | null;
|
|
107
|
+
};
|
|
108
|
+
/** `onVisit` açıkken `cache().prewarm` kökünde yasak olan klasik alanlar. */
|
|
109
|
+
export declare const CLASSIC_PREWARM_KEYS: string[];
|
|
110
|
+
/**
|
|
111
|
+
* HTML önbelleğinin girdi sınırı. 500 girdi ortalama bir sayfa boyutunda
|
|
112
|
+
* yaklaşık 100-200 MB tutar; uzun kuyruklu siteler bunu yükseltmek yerine
|
|
113
|
+
* veri önbelleğine yaslanmalı (bkz. `DEFAULT_DATA_CACHE`).
|
|
114
|
+
*/
|
|
115
|
+
export declare const DEFAULT_HTML_CACHE_MAX_ENTRIES = 500;
|
|
116
|
+
/**
|
|
117
|
+
* `notFound()` geçici bir upstream hatasına denk geldiğinde sayfanın kaç kez
|
|
118
|
+
* daha denenmesi gerektiği.
|
|
119
|
+
*
|
|
120
|
+
* Varsayılan tek deneme: maliyeti upstream'e binen ikinci bir istek turu, ama
|
|
121
|
+
* alternatifi var olan bir sayfayı 404 olarak servis etmek — arama motoru için
|
|
122
|
+
* geçici bir rate limit'in kalıcı kayba dönüşmesi. `attempts: 0` tekrarı
|
|
123
|
+
* kapatır ve doğrudan önbelleğe girmeyen 503'e düşer.
|
|
124
|
+
*/
|
|
125
|
+
export declare const DEFAULT_TRANSIENT_RETRY: {
|
|
126
|
+
attempts: number;
|
|
127
|
+
delayMs: number;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Upstream veri önbelleği.
|
|
131
|
+
*
|
|
132
|
+
* HTML önbelleğinden bilinçli olarak çok daha büyük: JSON, aynı sayfanın
|
|
133
|
+
* HTML'ine göre onlarca kat küçük. Uzun kuyruğu (on binlerce haber/etiket)
|
|
134
|
+
* HTML olarak tutmak imkânsız, verisini tutmak ise ucuz — ve API kotasını
|
|
135
|
+
* koruyan katman burası.
|
|
136
|
+
*/
|
|
137
|
+
export declare const DEFAULT_DATA_CACHE: {
|
|
138
|
+
maxEntries: number;
|
|
139
|
+
/**
|
|
140
|
+
* TTL dolduktan sonra girdinin kaç TTL boyunca daha kullanılabileceği.
|
|
141
|
+
* HTML'deki 1 katsayısından yüksek: bayat veri, eksik sayfadan iyidir ve
|
|
142
|
+
* upstream düştüğünde tek elde kalan şey budur.
|
|
143
|
+
*/
|
|
144
|
+
staleFactor: number;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Upstream API'ye giden isteklerin host başına hız freni.
|
|
148
|
+
*
|
|
149
|
+
* Varsayılan **kapalı** (`rate: 0`): fren, kotasını bilen bir uygulamanın
|
|
150
|
+
* bilinçli kararı. Açıldığında `rate` bir tavan olur ve gerçek hız 429
|
|
151
|
+
* cevaplarına göre kendini aşağı çeker (bkz. `src/server/upstream-limiter.js`).
|
|
152
|
+
*
|
|
153
|
+
* `hosts` ile tek tek uçlar ayrılabilir; API'lerin kotası aynı olmak zorunda
|
|
154
|
+
* değil:
|
|
155
|
+
*
|
|
156
|
+
* upstream: { rate: 10, hosts: { "api.example.com": { rate: 3 } } }
|
|
157
|
+
*/
|
|
158
|
+
export declare const DEFAULT_UPSTREAM_LIMIT: {
|
|
159
|
+
/** Saniyedeki en fazla çağrı. 0 → fren tamamen kapalı. */
|
|
160
|
+
rate: number;
|
|
161
|
+
/** Kova boyu; verilmezse bir saniyelik bütçe kadar patlamaya izin verilir. */
|
|
162
|
+
burst: number;
|
|
163
|
+
/** Aynı anda uçabilecek çağrı. Ortalama hızdan bağımsız: anlık baskıyı bağlar. */
|
|
164
|
+
concurrency: number;
|
|
165
|
+
/** Azalmanın dibi: hız buranın altına inmez, yoksa site tamamen durur. */
|
|
166
|
+
minRate: number;
|
|
167
|
+
/** Toplamsal artışın adımı (çağrı/saniye) ve periyodu. */
|
|
168
|
+
increaseStep: number;
|
|
169
|
+
increaseIntervalMs: number;
|
|
170
|
+
/**
|
|
171
|
+
* İki azalma arasındaki en kısa süre. Aynı anda uçan on çağrının hepsi 429
|
|
172
|
+
* dönerse hız on kez yarılanıp dibe vurmasın.
|
|
173
|
+
*/
|
|
174
|
+
decreaseIntervalMs: number;
|
|
175
|
+
/** Devre kesici: art arda kaç 429'dan sonra host'a hiç gidilmeyeceği. */
|
|
176
|
+
breakerFailures: number;
|
|
177
|
+
breakerCooldownMs: number;
|
|
178
|
+
/** @type {Record<string, Record<string, number>>} */
|
|
179
|
+
hosts: {};
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Opsiyonel Redis ikinci kademesi (L2).
|
|
183
|
+
*
|
|
184
|
+
* Redis **birincil store değil**: bellek içi önbellek (L1) aynen kalır, Redis
|
|
185
|
+
* iki iş yapar — L1'de bulunmayan bir sayfa için render'ı atlatmak ve
|
|
186
|
+
* invalidation'ı bütün node'lara yaymak. Tek instance çalışan bir kurulumda
|
|
187
|
+
* kazanç neredeyse yok; bu yüzden `enabled` varsayılan olarak kapalı.
|
|
188
|
+
*
|
|
189
|
+
* `storeEncoded` kapalı, çünkü sıkıştırılmış gövdeleri de paylaşmak girdi
|
|
190
|
+
* başına boyutu iki-üç katına çıkarır ve brotli'yi yeniden üretmek Redis'ten
|
|
191
|
+
* indirmekten çoğu zaman daha ucuz.
|
|
192
|
+
*/
|
|
193
|
+
export declare const DEFAULT_REDIS: {
|
|
194
|
+
enabled: boolean;
|
|
195
|
+
/** `redis://` ya da `rediss://`. Boşsa ioredis varsayılanı (localhost:6379). */
|
|
196
|
+
url: string | null;
|
|
197
|
+
/** Aynı Redis'i paylaşan birden fazla uygulamayı ayırır. */
|
|
198
|
+
namespace: string;
|
|
199
|
+
keyPrefix: string;
|
|
200
|
+
/** HTML gövdeleri paylaşılsın mı. */
|
|
201
|
+
html: boolean;
|
|
202
|
+
/** Veri önbelleği paylaşılsın mı. */
|
|
203
|
+
data: boolean;
|
|
204
|
+
/** Brotli/gzip gövdeleri de paylaşılsın mı. */
|
|
205
|
+
storeEncoded: boolean;
|
|
206
|
+
/** pub/sub üzerinden invalidation yayını. */
|
|
207
|
+
events: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Tek bir komutun en fazla bekletebileceği süre. Önbellek okuması isteği
|
|
210
|
+
* bloklayan bir adım: Redis takıldığında render'a düşmek, ağı beklemekten
|
|
211
|
+
* iyidir.
|
|
212
|
+
*/
|
|
213
|
+
commandTimeoutMs: number;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Kalıcı log sink'leri (dosya + S3).
|
|
217
|
+
*
|
|
218
|
+
* Varsayılan her şey kapalı: stdout ve admin ring mevcut davranışını korur.
|
|
219
|
+
* `kinds` hangi structured kayıtların sink'lere gideceğini seçer; `console`
|
|
220
|
+
* runtime `http`/`event`/`error` satırlarının terminalde görünmesini kontrol
|
|
221
|
+
* eder (banner/build satırlarına dokunmaz).
|
|
222
|
+
*
|
|
223
|
+
* S3 credential'ları config'e yazılmaz — `JSKELET_S3_ACCESS_KEY_ID` /
|
|
224
|
+
* `JSKELET_S3_SECRET_ACCESS_KEY` (ve isteğe bağlı `JSKELET_S3_SESSION_TOKEN`).
|
|
225
|
+
* Bucket için `JSKELET_LOG_BUCKET` (veya `JSKELET_S3_BUCKET`) env'i config'i
|
|
226
|
+
* ezer ve `ayberkenis/jskelet/logs` gibi `bucket/prefix` yolunu kabul eder.
|
|
227
|
+
* Uyumlu API adresi `JSKELET_S3_API_URL` (S3-compatible endpoint).
|
|
228
|
+
*/
|
|
229
|
+
export declare const DEFAULT_LOGS: {
|
|
230
|
+
console: boolean;
|
|
231
|
+
/** @type {Array<"http" | "event" | "error">} */
|
|
232
|
+
kinds: Array<"http" | "event" | "error">;
|
|
233
|
+
file: {
|
|
234
|
+
enabled: boolean;
|
|
235
|
+
/** Proje köküne göre relative. */
|
|
236
|
+
dir: string;
|
|
237
|
+
/** Yalnızca günlük rotasyon. */
|
|
238
|
+
rotate: "daily";
|
|
239
|
+
};
|
|
240
|
+
s3: {
|
|
241
|
+
enabled: boolean;
|
|
242
|
+
/** @type {string | null} */
|
|
243
|
+
bucket: string | null;
|
|
244
|
+
prefix: string;
|
|
245
|
+
/** @type {string | null} */
|
|
246
|
+
region: string | null;
|
|
247
|
+
/** MinIO vb. için; null → AWS. */
|
|
248
|
+
/** @type {string | null} */
|
|
249
|
+
endpoint: string | null;
|
|
250
|
+
flushIntervalMs: number;
|
|
251
|
+
maxBatch: number;
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
/**
|
|
255
|
+
* Framework yönetim paneli (`/_jskelet/admin`).
|
|
256
|
+
*
|
|
257
|
+
* `enabled` varsayılan olarak **kapalı** ve ortama bakmaz: panel açıldığında
|
|
258
|
+
* production'da da çalışır, ama açılması bilinçli bir karar olmalı. Kapalıyken
|
|
259
|
+
* router hiç mount edilmez — yolun kendisi de yok, yani 404 dönen bir uç bile
|
|
260
|
+
* ortaya çıkmaz.
|
|
261
|
+
*
|
|
262
|
+
* Şifre her süreç başlangıcında yeniden üretilir (bkz. `src/server/admin/`):
|
|
263
|
+
* panelin ömrü sürecin ömrü kadardır ve bir deploy eski erişimi otomatik
|
|
264
|
+
* olarak iptal eder. Bu yüzden config'te şifre alanı yok.
|
|
265
|
+
*/
|
|
266
|
+
export declare const DEFAULT_ADMIN: {
|
|
267
|
+
enabled: boolean;
|
|
268
|
+
basePath: string;
|
|
269
|
+
/**
|
|
270
|
+
* Boş dizi = IP kısıtı yok. Exact IP veya CIDR (`10.0.0.0/8`); listede
|
|
271
|
+
* olmayan her istek 404 (login dahil).
|
|
272
|
+
* @type {string[]}
|
|
273
|
+
*/
|
|
274
|
+
allowIps: string[];
|
|
275
|
+
/** Bilinen crawler / bot UA'ları 404 ile reddedilsin mi. */
|
|
276
|
+
blockBots: boolean;
|
|
277
|
+
/** Kaç başarısız denemeden sonra IP yasaklanır. */
|
|
278
|
+
banAttempts: number;
|
|
279
|
+
/** Yasağın süresi. */
|
|
280
|
+
banHours: number;
|
|
281
|
+
/** Oturumun ömrü; süreç yeniden başladığında zaten sıfırlanır. */
|
|
282
|
+
sessionHours: number;
|
|
283
|
+
/** Canlı log ring boyutu (HTTP + framework olayları). */
|
|
284
|
+
logSize: number;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Cloudflare cache yüzeyi.
|
|
288
|
+
*
|
|
289
|
+
* JSkelet'in önbelleği origin önbelleği; ziyaretçinin gördüğü kopya CDN'de.
|
|
290
|
+
* Bu bölüm ikisini aynı panelden yönetilebilir kılar (bkz.
|
|
291
|
+
* `src/server/cloudflare.js`).
|
|
292
|
+
*
|
|
293
|
+
* Token **config'e yazılmamalı**: `JSKELET_CLOUDFLARE_KEY` env'i önceliklidir
|
|
294
|
+
* ve önerilen yol odur. Zone kimliği sır değil, ama o da env'den okunabilir
|
|
295
|
+
* (`JSKELET_CLOUDFLARE_ZONE_ID`).
|
|
296
|
+
*
|
|
297
|
+
* Gereken token izinleri: purge için `Zone.Cache Purge`, ayarlar için
|
|
298
|
+
* `Zone.Zone Settings`, analitik için `Zone.Analytics` (salt okunur).
|
|
299
|
+
*/
|
|
300
|
+
export declare const DEFAULT_CLOUDFLARE: {
|
|
301
|
+
/** `false` verilirse env'de token olsa bile yüzey kapalı kalır. */
|
|
302
|
+
enabled: boolean;
|
|
303
|
+
/** @type {string | null} */
|
|
304
|
+
zoneId: string | null;
|
|
305
|
+
/** @type {string | null} Env tercih edilir; burada tutmak sırrı repoya sokar. */
|
|
306
|
+
apiToken: string | null;
|
|
307
|
+
/**
|
|
308
|
+
* Purge, tam URL istiyor; panel elinde yalnızca yol tutuyor. Site adı
|
|
309
|
+
* verilmezse purge isteğinin geldiği istek origin'i kullanılır.
|
|
310
|
+
* @type {string | null}
|
|
311
|
+
*/
|
|
312
|
+
hostname: string | null;
|
|
313
|
+
/** Analitik penceresi (saat). Cloudflare'in izin verdiği aralıkla sınırlı. */
|
|
314
|
+
analyticsHours: number;
|
|
315
|
+
};
|
|
316
|
+
/** Oturuma bağlı sayfalar ısıtılmaz; uygulama kendi listesini verebilir. */
|
|
317
|
+
export declare const DEFAULT_PREWARM_SKIP: string[];
|
|
318
|
+
/**
|
|
319
|
+
* Site içi gezinme ipuçları (Speculation Rules + view transition).
|
|
320
|
+
*
|
|
321
|
+
* Varsayılan bilinçli olarak ölçülü: `prefetch` açık, çünkü yalnızca belgeyi
|
|
322
|
+
* indirir ve sayfanın JS'ini çalıştırmaz — yanlış tahmin edilse bile tek
|
|
323
|
+
* maliyeti bir istektir. `prerender` kapalı, çünkü hedef sayfanın script'leri
|
|
324
|
+
* gerçekten çalışır; ölçüm kodunu `prerenderingchange` olayına bağlamayan bir
|
|
325
|
+
* uygulamada ziyaret sayıları şişer. `viewTransition` kapalı, çünkü uygulamanın
|
|
326
|
+
* kendi geçiş animasyonlarıyla çakışabilir.
|
|
327
|
+
*/
|
|
328
|
+
export declare const DEFAULT_NAVIGATION: {
|
|
329
|
+
/** `false` ya da eagerness: "conservative" | "moderate" | "eager". */
|
|
330
|
+
prefetch: false | "conservative" | "moderate" | "eager";
|
|
331
|
+
/** @type {false | "conservative" | "moderate" | "eager"} */
|
|
332
|
+
prerender: false | "conservative" | "moderate" | "eager";
|
|
333
|
+
/** `@view-transition { navigation: auto }` basılsın mı. */
|
|
334
|
+
viewTransition: boolean;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Hiçbir koşulda önden getirilmeyecek yollar. Yan etkisi olan ya da gezinme
|
|
338
|
+
* hedefi olmayan uçların spekülatif istekle tetiklenmesi gerçek bir hata
|
|
339
|
+
* kaynağı; uygulama kendi listesini `navigation.exclude` ile ekler.
|
|
340
|
+
*/
|
|
341
|
+
export declare const DEFAULT_NAVIGATION_EXCLUDE: string[];
|
|
342
|
+
/**
|
|
343
|
+
* Güvenlik ayarları.
|
|
344
|
+
*
|
|
345
|
+
* `trustProxy` varsayılan olarak açık, çünkü JSkelet uygulamaları neredeyse
|
|
346
|
+
* her zaman bir ters proxy arkasında koşuyor ve doğru protokol/IP buna bağlı.
|
|
347
|
+
* Ama doğrudan internete açık bir sunucuda bu, istemcinin `X-Forwarded-For`
|
|
348
|
+
* uydurabilmesi demek — rate limit ve audit log girdiğinde kapatılmalı.
|
|
349
|
+
*
|
|
350
|
+
* `csrf.enabled` açık: framework gövdeyi kendisi ayrıştırdığı için bu yüzey
|
|
351
|
+
* onun sorumluluğu. Kontrol yalnızca **çapraz site olduğu belli** istekleri
|
|
352
|
+
* reddeder (`Origin` uyuşmuyor ya da `Sec-Fetch-Site: cross-site`); başlık
|
|
353
|
+
* hiç yoksa geçer, böylece webhook ve sunucudan sunucuya çağrılar bozulmaz.
|
|
354
|
+
*
|
|
355
|
+
* `csrf.token` kapalı: çift gönderim token'ı `Origin` göndermeyen eski
|
|
356
|
+
* tarayıcılar için ikinci katman ve formlara `csrfField()` eklenmesini
|
|
357
|
+
* gerektiriyor, yani açılması bilinçli bir karar olmalı.
|
|
358
|
+
*/
|
|
359
|
+
export declare const DEFAULT_SECURITY: {
|
|
360
|
+
trustProxy: boolean;
|
|
361
|
+
/** @type {string | null} */
|
|
362
|
+
cookieSecret: string | null;
|
|
363
|
+
csrf: {
|
|
364
|
+
enabled: boolean;
|
|
365
|
+
token: boolean;
|
|
366
|
+
/** Ek olarak kabul edilen origin'ler (ör. ayrı bir admin alan adı). */
|
|
367
|
+
allowedOrigins: string[];
|
|
368
|
+
/** Kontrolden muaf yollar — webhook uçları buraya yazılır. */
|
|
369
|
+
exclude: string[];
|
|
370
|
+
cookieName: string;
|
|
371
|
+
fieldName: string;
|
|
372
|
+
headerName: string;
|
|
373
|
+
};
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Build-zamanı görsel adımı + opsiyonel runtime uzak görsel proxy.
|
|
377
|
+
*
|
|
378
|
+
* `remote` kapalıyken `image()` uzak URL'leri olduğu gibi basar (eski davranış).
|
|
379
|
+
* Açılınca yalnızca `allowHosts` listesindeki host'lar proxy edilir — boş liste
|
|
380
|
+
* açık proxy / SSRF kapısı olurdu, bu yüzden allowHosts olmadan remote hiç
|
|
381
|
+
* mount edilmez.
|
|
382
|
+
*/
|
|
383
|
+
export declare const DEFAULT_IMAGES: {
|
|
384
|
+
widths: number[];
|
|
385
|
+
quality: number;
|
|
386
|
+
skip: string[];
|
|
387
|
+
remote: {
|
|
388
|
+
/** @type {string[]} */
|
|
389
|
+
allowHosts: string[];
|
|
390
|
+
path: string;
|
|
391
|
+
/** İzin verilen en büyük `w` (retina üstü israf). */
|
|
392
|
+
maxWidth: number;
|
|
393
|
+
/** Disk önbelleği Cache-Control max-age (saniye). */
|
|
394
|
+
cacheMaxAge: number;
|
|
395
|
+
fetchTimeoutMs: number;
|
|
396
|
+
/** Upstream gövde üst sınırı; aşılırsa 502. */
|
|
397
|
+
maxBytes: number;
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Markalama. Header adı ve dev overlay yolu tek yerden değişsin diye
|
|
402
|
+
* config'ten okunur — fork eden proje kendi adını verebilir.
|
|
403
|
+
*/
|
|
404
|
+
export declare const DEFAULT_BRAND: {
|
|
405
|
+
name: string;
|
|
406
|
+
/** `<html lang>`; uygulama kendi dilini config'te bildirir. */
|
|
407
|
+
lang: string;
|
|
408
|
+
poweredBy: string;
|
|
409
|
+
cacheHeader: string;
|
|
410
|
+
devBasePath: string;
|
|
411
|
+
prewarmUserAgent: string;
|
|
412
|
+
devTokenCookie: string;
|
|
413
|
+
/**
|
|
414
|
+
* Paylaşımlı cookie Domain kökleri (örn. `.investvio.com`, `.localhost`).
|
|
415
|
+
* `writeSharedCookie` host bunlardan birine uyuyorsa Domain olarak yazar.
|
|
416
|
+
* @type {string[]}
|
|
417
|
+
*/
|
|
418
|
+
sharedCookieRoots: string[];
|
|
419
|
+
};
|
|
420
|
+
/**
|
|
421
|
+
* Kimlik / alt alan handoff. Framework oturum vermez; yalnızca çapraz-subdomain
|
|
422
|
+
* cookie köprüsü opsiyoneldir.
|
|
423
|
+
*/
|
|
424
|
+
export declare const DEFAULT_AUTH: {
|
|
425
|
+
/**
|
|
426
|
+
* `true` veya `{ allowedCookieNames, ttlSeconds?, path?, maxValueBytes?,
|
|
427
|
+
* maxPendingTickets?, maxMintsPerIpPerMinute? }`.
|
|
428
|
+
* Açıkken `POST /_jskelet/auth/handoff` ve `?handoff=` redeem middleware'i.
|
|
429
|
+
* Mint için `allowedCookieNames` dolu olmalı (aksi halde 400).
|
|
430
|
+
* @type {boolean | {
|
|
431
|
+
* enabled?: boolean,
|
|
432
|
+
* allowedCookieNames?: string[],
|
|
433
|
+
* ttlSeconds?: number,
|
|
434
|
+
* path?: string,
|
|
435
|
+
* maxValueBytes?: number,
|
|
436
|
+
* maxPendingTickets?: number,
|
|
437
|
+
* maxMintsPerIpPerMinute?: number,
|
|
438
|
+
* }}
|
|
439
|
+
*/
|
|
440
|
+
crossSubdomainHandoff: boolean | {
|
|
441
|
+
enabled?: boolean;
|
|
442
|
+
allowedCookieNames?: string[];
|
|
443
|
+
ttlSeconds?: number;
|
|
444
|
+
path?: string;
|
|
445
|
+
maxValueBytes?: number;
|
|
446
|
+
maxPendingTickets?: number;
|
|
447
|
+
maxMintsPerIpPerMinute?: number;
|
|
448
|
+
};
|
|
449
|
+
};
|