jskelet 0.6.3 → 0.6.4
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 +136 -136
- package/CHANGELOG.md +628 -620
- package/LICENSE +21 -21
- package/README.md +2 -0
- package/bin/jskelet.mjs +130 -130
- package/docs/01-baslangic.md +291 -291
- package/docs/02-mimari.md +310 -310
- package/docs/03-routing.md +515 -515
- package/docs/04-render-ve-sablonlar.md +667 -661
- package/docs/05-islands.md +486 -486
- package/docs/06-cache.md +1467 -1443
- package/docs/07-yapilandirma.md +1208 -1197
- package/docs/08-build.md +429 -429
- package/docs/09-dev-araclari.md +364 -364
- package/docs/10-dagitim.md +348 -338
- package/docs/12-panel-ve-oturum.md +479 -478
- package/docs/README.md +83 -83
- package/docs/en/01-getting-started.md +298 -298
- package/docs/en/02-architecture.md +329 -329
- package/docs/en/03-routing.md +531 -531
- package/docs/en/04-rendering.md +675 -669
- package/docs/en/05-islands.md +497 -497
- package/docs/en/06-caching.md +1476 -1453
- package/docs/en/07-configuration.md +1229 -1219
- package/docs/en/08-build.md +447 -447
- package/docs/en/09-dev-tools.md +373 -373
- package/docs/en/10-deployment.md +351 -340
- package/docs/en/11-migration.md +398 -398
- package/docs/en/12-dashboards-and-sessions.md +489 -488
- package/docs/en/README.md +87 -87
- package/package.json +137 -137
- package/src/build/ensure-build.mjs +19 -19
- package/src/build/paths.mjs +153 -153
- package/src/build/resolve-peer.mjs +36 -36
- package/src/build/tasks/client.mjs +349 -349
- package/src/build/tasks/css.mjs +235 -235
- package/src/build/tasks/fonts.mjs +146 -146
- package/src/build/tasks/icons.mjs +357 -357
- package/src/build/tasks/images.mjs +244 -244
- package/src/build/tasks/precompress.mjs +78 -78
- package/src/build/tasks/templates.mjs +20 -20
- package/src/client/admin/i18n.js +764 -764
- package/src/client/admin/login.html +74 -74
- package/src/client/admin/panel.css +809 -809
- package/src/client/admin/panel.html +495 -495
- package/src/client/admin/panel.js +1251 -1251
- package/src/client/devtools/report.html +185 -185
- package/src/client/devtools/report.js +745 -745
- package/src/client/devtools/seo.js +628 -628
- package/src/client/dom.js +95 -95
- package/src/client/form.js +192 -192
- package/src/client/index.js +45 -45
- package/src/client/registry.js +305 -305
- package/src/client/safe-image.js +91 -91
- package/src/client/shared-cookie.js +225 -225
- package/src/client/store.js +36 -36
- package/src/client/swap.js +188 -188
- package/src/compile/codegen.js +336 -336
- package/src/compile/compile-all.js +149 -149
- package/src/compile/errors.js +66 -66
- package/src/compile/expr.js +409 -409
- package/src/compile/index.js +17 -17
- package/src/compile/parse.js +541 -541
- package/src/compile/resolve.js +211 -211
- package/src/compile/scan-exports.js +51 -51
- package/src/config/defaults.js +541 -534
- package/src/config/index.js +1500 -1469
- package/src/config/pattern.js +107 -107
- package/src/generate.mjs +163 -163
- package/src/http/control-flow.js +71 -71
- package/src/http/cookies-entry.js +21 -21
- package/src/http/cookies.js +277 -277
- package/src/http/request-cache.js +46 -46
- package/src/http/request-context.js +165 -165
- package/src/http/shared-cookie.js +178 -178
- package/src/index.js +101 -101
- package/src/init.mjs +232 -230
- package/src/migrate/apply.mjs +262 -262
- package/src/migrate/babel.mjs +79 -79
- package/src/migrate/classify.mjs +155 -155
- package/src/migrate/config.mjs +126 -126
- package/src/migrate/fs-walk.mjs +191 -191
- package/src/migrate/parse.mjs +26 -26
- package/src/migrate/scan.mjs +177 -177
- package/src/migrate/transform/expr-source.mjs +168 -168
- package/src/migrate/transform/island.mjs +67 -67
- package/src/migrate/transform/jsx-to-component.mjs +302 -302
- package/src/migrate/transform/jsx-to-jsk.mjs +330 -330
- package/src/migrate/transform/page-split.mjs +435 -435
- package/src/migrate/write.mjs +81 -81
- package/src/migrate.mjs +171 -171
- package/src/runtime/alias-hooks.mjs +119 -119
- package/src/runtime/register.mjs +4 -4
- package/src/server/admin/actions.js +229 -229
- package/src/server/admin/auth.js +125 -125
- package/src/server/admin/event-log.js +151 -151
- package/src/server/admin/gate.js +209 -209
- package/src/server/admin/inventory.js +188 -188
- package/src/server/admin/mount.js +56 -56
- package/src/server/admin/router.js +216 -216
- package/src/server/admin/snapshot.js +241 -241
- package/src/server/assets.js +147 -147
- package/src/server/auth/handoff.js +309 -309
- package/src/server/cache-blob.js +70 -70
- package/src/server/cache-control.js +45 -0
- package/src/server/cache-deps.js +42 -42
- package/src/server/cache-vary.js +113 -113
- package/src/server/cloudflare.js +607 -607
- package/src/server/create-app.js +366 -366
- package/src/server/data-cache.js +553 -553
- package/src/server/dev/report.js +485 -485
- package/src/server/dev/socket.js +170 -170
- package/src/server/dev/version-check.mjs +139 -139
- package/src/server/disk-cache.js +233 -233
- package/src/server/ejs-adapter.js +59 -59
- package/src/server/html-cache.js +1196 -1196
- package/src/server/image-optimizer.js +500 -500
- package/src/server/logs/access-middleware.js +66 -66
- package/src/server/logs/file-sink.js +193 -193
- package/src/server/logs/pipeline.js +165 -165
- package/src/server/logs/s3-put.js +214 -214
- package/src/server/logs/s3-sink.js +112 -112
- package/src/server/metadata.js +102 -102
- package/src/server/middleware/compression.js +205 -205
- package/src/server/middleware/csrf.js +134 -134
- package/src/server/middleware/dev-gate.js +75 -75
- package/src/server/middleware/headers.js +37 -37
- package/src/server/middleware/redirects.js +32 -32
- package/src/server/middleware/robots-txt.js +341 -341
- package/src/server/middleware/static-precompressed.js +121 -121
- package/src/server/middleware/trailing-slash.js +53 -53
- package/src/server/middleware/upstream-proxy.js +141 -141
- package/src/server/og-image.js +369 -356
- package/src/server/port-guard.js +255 -255
- package/src/server/prewarm.js +1082 -1082
- package/src/server/redis.js +588 -588
- package/src/server/render.js +910 -910
- package/src/server/router.js +157 -157
- package/src/server/status-page.js +265 -265
- package/src/server/upstream-limiter.js +376 -376
- package/src/server/upstream-tracking.js +166 -166
- package/src/shared/cookie-domain.js +66 -66
- package/src/start.mjs +22 -22
- package/src/templates/layout.ejs +30 -30
- package/src/templates/layout.jsk +30 -30
- package/src/version.mjs +31 -31
- package/src/views/components/loader.js +101 -101
- package/src/views/helpers/html.js +102 -102
- package/src/views/helpers/tags.js +375 -375
- package/types/config/defaults.d.ts +6 -0
- package/types/config/index.d.ts +6 -0
- package/types/server/cache-control.d.ts +28 -0
- package/types/server/og-image.d.ts +5 -0
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `next/font/google` yerine self-host font dosyaları.
|
|
3
|
-
*
|
|
4
|
-
* Dosyalar `public/fonts/` altında **sabit isimlerle** durur (hash yok), çünkü
|
|
5
|
-
* `@font-face` içindeki `url()` yolları elle yazılıyor; hash'lemek her build'de
|
|
6
|
-
* stylesheet'i de değiştirmek zorunda bırakırdı.
|
|
7
|
-
*
|
|
8
|
-
* Dosya yoksa bir kez Google Fonts'tan indirilir ve **commit edilmesi
|
|
9
|
-
* beklenir**: build'in ağa bağımlı olması CI'da kırılgan. İndirme başarısız
|
|
10
|
-
* olursa uyarı basılır ve sayfa sistem font yığınına düşer — build durmaz.
|
|
11
|
-
*
|
|
12
|
-
* Yapılandırma:
|
|
13
|
-
* fonts: [{ family: "Inter", weights: [400, 700] }]
|
|
14
|
-
* Çıktı: `public/fonts/inter-400.woff2`, manifest anahtarı aynı dosya adı.
|
|
15
|
-
*/
|
|
16
|
-
import fs from "node:fs";
|
|
17
|
-
import path from "node:path";
|
|
18
|
-
import * as log from "../../log.mjs";
|
|
19
|
-
|
|
20
|
-
/** woff2 döndürmesi için modern tarayıcı UA'sı gerekir. */
|
|
21
|
-
const UA =
|
|
22
|
-
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
|
|
23
|
-
"(KHTML, like Gecko) Chrome/124.0 Safari/537.36";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @param {string} family
|
|
27
|
-
* @returns {string}
|
|
28
|
-
*/
|
|
29
|
-
function toSlug(family) {
|
|
30
|
-
return family.trim().toLowerCase().replace(/\s+/g, "-");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @param {string} family
|
|
35
|
-
* @param {number[]} weights
|
|
36
|
-
* @returns {string}
|
|
37
|
-
*/
|
|
38
|
-
function cssUrl(family, weights) {
|
|
39
|
-
const name = family.trim().replace(/\s+/g, "+");
|
|
40
|
-
const wght = [...weights].sort((a, b) => a - b).join(";");
|
|
41
|
-
return `https://fonts.googleapis.com/css2?family=${name}:wght@${wght}&display=swap`;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @param {import('../../config/index.js').ResolvedConfig} config
|
|
46
|
-
* @returns {Promise<Record<string, string>>}
|
|
47
|
-
*/
|
|
48
|
-
export async function copyFonts(config) {
|
|
49
|
-
const fontsDir = config.dirs.fonts;
|
|
50
|
-
fs.mkdirSync(fontsDir, { recursive: true });
|
|
51
|
-
|
|
52
|
-
/** @type {Record<string, string>} */
|
|
53
|
-
const manifest = {};
|
|
54
|
-
let expected = 0;
|
|
55
|
-
|
|
56
|
-
for (const family of config.fonts) {
|
|
57
|
-
const slug = family.slug ?? toSlug(family.family);
|
|
58
|
-
const weights = family.weights ?? [400];
|
|
59
|
-
expected += weights.length;
|
|
60
|
-
|
|
61
|
-
/** @type {number[]} */
|
|
62
|
-
const missing = [];
|
|
63
|
-
|
|
64
|
-
for (const weight of weights) {
|
|
65
|
-
const fileName = `${slug}-${weight}.woff2`;
|
|
66
|
-
if (fs.existsSync(path.join(fontsDir, fileName))) {
|
|
67
|
-
manifest[fileName] = `/fonts/${fileName}`;
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
missing.push(weight);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!missing.length) continue;
|
|
74
|
-
|
|
75
|
-
const downloaded = await downloadFromGoogle(
|
|
76
|
-
cssUrl(family.family, missing),
|
|
77
|
-
missing,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
for (const [weight, buffer] of downloaded) {
|
|
81
|
-
const fileName = `${slug}-${weight}.woff2`;
|
|
82
|
-
fs.writeFileSync(path.join(fontsDir, fileName), buffer);
|
|
83
|
-
manifest[fileName] = `/fonts/${fileName}`;
|
|
84
|
-
log.detail(`${fileName} downloaded (${log.size(buffer.byteLength)})`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const stillMissing = missing.filter(
|
|
88
|
-
(weight) => !manifest[`${slug}-${weight}.woff2`],
|
|
89
|
-
);
|
|
90
|
-
if (stillMissing.length) {
|
|
91
|
-
log.warn(
|
|
92
|
-
`${family.family} ${stillMissing.join(", ")} could not be downloaded — falling back to the system font stack.`,
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
log.summary(`${Object.keys(manifest).length}/${expected} weights`);
|
|
98
|
-
return manifest;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Google'ın döndürdüğü CSS'te her ağırlık ve her subset için ayrı bir
|
|
103
|
-
* `@font-face` bloğu var. Latin subset'i (`U+0000-00FF`) seçilir: diğerleri
|
|
104
|
-
* çoğu site için ölü ağırlık ve `unicode-range` olmadan hepsini indirmek
|
|
105
|
-
* font boyutunu katlar.
|
|
106
|
-
*
|
|
107
|
-
* @param {string} url
|
|
108
|
-
* @param {number[]} weights
|
|
109
|
-
* @returns {Promise<[number, Buffer][]>}
|
|
110
|
-
*/
|
|
111
|
-
async function downloadFromGoogle(url, weights) {
|
|
112
|
-
/** @type {[number, Buffer][]} */
|
|
113
|
-
const out = [];
|
|
114
|
-
|
|
115
|
-
let css;
|
|
116
|
-
try {
|
|
117
|
-
const response = await fetch(url, { headers: { "User-Agent": UA } });
|
|
118
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
119
|
-
css = await response.text();
|
|
120
|
-
} catch (error) {
|
|
121
|
-
log.warn(`could not fetch Google Fonts CSS (${error.message})`);
|
|
122
|
-
return out;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const blocks = css.split("@font-face").slice(1);
|
|
126
|
-
|
|
127
|
-
for (const weight of weights) {
|
|
128
|
-
const block = blocks.find(
|
|
129
|
-
(candidate) =>
|
|
130
|
-
candidate.includes(`font-weight: ${weight}`) &&
|
|
131
|
-
candidate.includes("U+0000-00FF"),
|
|
132
|
-
);
|
|
133
|
-
const fileUrl = block?.match(/url\((https:[^)]+\.woff2)\)/)?.[1];
|
|
134
|
-
if (!fileUrl) continue;
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
const response = await fetch(fileUrl, { headers: { "User-Agent": UA } });
|
|
138
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
139
|
-
out.push([weight, Buffer.from(await response.arrayBuffer())]);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
log.warn(`${weight} could not be downloaded (${error.message})`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return out;
|
|
146
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* `next/font/google` yerine self-host font dosyaları.
|
|
3
|
+
*
|
|
4
|
+
* Dosyalar `public/fonts/` altında **sabit isimlerle** durur (hash yok), çünkü
|
|
5
|
+
* `@font-face` içindeki `url()` yolları elle yazılıyor; hash'lemek her build'de
|
|
6
|
+
* stylesheet'i de değiştirmek zorunda bırakırdı.
|
|
7
|
+
*
|
|
8
|
+
* Dosya yoksa bir kez Google Fonts'tan indirilir ve **commit edilmesi
|
|
9
|
+
* beklenir**: build'in ağa bağımlı olması CI'da kırılgan. İndirme başarısız
|
|
10
|
+
* olursa uyarı basılır ve sayfa sistem font yığınına düşer — build durmaz.
|
|
11
|
+
*
|
|
12
|
+
* Yapılandırma:
|
|
13
|
+
* fonts: [{ family: "Inter", weights: [400, 700] }]
|
|
14
|
+
* Çıktı: `public/fonts/inter-400.woff2`, manifest anahtarı aynı dosya adı.
|
|
15
|
+
*/
|
|
16
|
+
import fs from "node:fs";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
import * as log from "../../log.mjs";
|
|
19
|
+
|
|
20
|
+
/** woff2 döndürmesi için modern tarayıcı UA'sı gerekir. */
|
|
21
|
+
const UA =
|
|
22
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
|
|
23
|
+
"(KHTML, like Gecko) Chrome/124.0 Safari/537.36";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {string} family
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
function toSlug(family) {
|
|
30
|
+
return family.trim().toLowerCase().replace(/\s+/g, "-");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {string} family
|
|
35
|
+
* @param {number[]} weights
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
function cssUrl(family, weights) {
|
|
39
|
+
const name = family.trim().replace(/\s+/g, "+");
|
|
40
|
+
const wght = [...weights].sort((a, b) => a - b).join(";");
|
|
41
|
+
return `https://fonts.googleapis.com/css2?family=${name}:wght@${wght}&display=swap`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {import('../../config/index.js').ResolvedConfig} config
|
|
46
|
+
* @returns {Promise<Record<string, string>>}
|
|
47
|
+
*/
|
|
48
|
+
export async function copyFonts(config) {
|
|
49
|
+
const fontsDir = config.dirs.fonts;
|
|
50
|
+
fs.mkdirSync(fontsDir, { recursive: true });
|
|
51
|
+
|
|
52
|
+
/** @type {Record<string, string>} */
|
|
53
|
+
const manifest = {};
|
|
54
|
+
let expected = 0;
|
|
55
|
+
|
|
56
|
+
for (const family of config.fonts) {
|
|
57
|
+
const slug = family.slug ?? toSlug(family.family);
|
|
58
|
+
const weights = family.weights ?? [400];
|
|
59
|
+
expected += weights.length;
|
|
60
|
+
|
|
61
|
+
/** @type {number[]} */
|
|
62
|
+
const missing = [];
|
|
63
|
+
|
|
64
|
+
for (const weight of weights) {
|
|
65
|
+
const fileName = `${slug}-${weight}.woff2`;
|
|
66
|
+
if (fs.existsSync(path.join(fontsDir, fileName))) {
|
|
67
|
+
manifest[fileName] = `/fonts/${fileName}`;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
missing.push(weight);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!missing.length) continue;
|
|
74
|
+
|
|
75
|
+
const downloaded = await downloadFromGoogle(
|
|
76
|
+
cssUrl(family.family, missing),
|
|
77
|
+
missing,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
for (const [weight, buffer] of downloaded) {
|
|
81
|
+
const fileName = `${slug}-${weight}.woff2`;
|
|
82
|
+
fs.writeFileSync(path.join(fontsDir, fileName), buffer);
|
|
83
|
+
manifest[fileName] = `/fonts/${fileName}`;
|
|
84
|
+
log.detail(`${fileName} downloaded (${log.size(buffer.byteLength)})`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const stillMissing = missing.filter(
|
|
88
|
+
(weight) => !manifest[`${slug}-${weight}.woff2`],
|
|
89
|
+
);
|
|
90
|
+
if (stillMissing.length) {
|
|
91
|
+
log.warn(
|
|
92
|
+
`${family.family} ${stillMissing.join(", ")} could not be downloaded — falling back to the system font stack.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
log.summary(`${Object.keys(manifest).length}/${expected} weights`);
|
|
98
|
+
return manifest;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Google'ın döndürdüğü CSS'te her ağırlık ve her subset için ayrı bir
|
|
103
|
+
* `@font-face` bloğu var. Latin subset'i (`U+0000-00FF`) seçilir: diğerleri
|
|
104
|
+
* çoğu site için ölü ağırlık ve `unicode-range` olmadan hepsini indirmek
|
|
105
|
+
* font boyutunu katlar.
|
|
106
|
+
*
|
|
107
|
+
* @param {string} url
|
|
108
|
+
* @param {number[]} weights
|
|
109
|
+
* @returns {Promise<[number, Buffer][]>}
|
|
110
|
+
*/
|
|
111
|
+
async function downloadFromGoogle(url, weights) {
|
|
112
|
+
/** @type {[number, Buffer][]} */
|
|
113
|
+
const out = [];
|
|
114
|
+
|
|
115
|
+
let css;
|
|
116
|
+
try {
|
|
117
|
+
const response = await fetch(url, { headers: { "User-Agent": UA } });
|
|
118
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
119
|
+
css = await response.text();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
log.warn(`could not fetch Google Fonts CSS (${error.message})`);
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const blocks = css.split("@font-face").slice(1);
|
|
126
|
+
|
|
127
|
+
for (const weight of weights) {
|
|
128
|
+
const block = blocks.find(
|
|
129
|
+
(candidate) =>
|
|
130
|
+
candidate.includes(`font-weight: ${weight}`) &&
|
|
131
|
+
candidate.includes("U+0000-00FF"),
|
|
132
|
+
);
|
|
133
|
+
const fileUrl = block?.match(/url\((https:[^)]+\.woff2)\)/)?.[1];
|
|
134
|
+
if (!fileUrl) continue;
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const response = await fetch(fileUrl, { headers: { "User-Agent": UA } });
|
|
138
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
139
|
+
out.push([weight, Buffer.from(await response.arrayBuffer())]);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
log.warn(`${weight} could not be downloaded (${error.message})`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return out;
|
|
146
|
+
}
|