jskelet 0.6.1 → 0.6.3
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 +620 -596
- package/LICENSE +21 -21
- package/bin/jskelet.mjs +130 -130
- package/docs/01-baslangic.md +291 -291
- package/docs/02-mimari.md +310 -309
- package/docs/03-routing.md +515 -515
- package/docs/04-render-ve-sablonlar.md +661 -661
- package/docs/05-islands.md +486 -486
- package/docs/06-cache.md +1443 -1423
- package/docs/07-yapilandirma.md +12 -6
- package/docs/08-build.md +429 -428
- package/docs/09-dev-araclari.md +364 -364
- package/docs/10-dagitim.md +338 -338
- package/docs/12-panel-ve-oturum.md +478 -478
- package/docs/README.md +83 -83
- package/docs/en/01-getting-started.md +298 -298
- package/docs/en/02-architecture.md +329 -328
- package/docs/en/03-routing.md +531 -531
- package/docs/en/04-rendering.md +669 -669
- package/docs/en/05-islands.md +497 -497
- package/docs/en/06-caching.md +1453 -1431
- package/docs/en/07-configuration.md +1219 -1214
- package/docs/en/08-build.md +447 -446
- package/docs/en/09-dev-tools.md +373 -373
- package/docs/en/10-deployment.md +340 -340
- package/docs/en/11-migration.md +398 -398
- package/docs/en/12-dashboards-and-sessions.md +488 -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 +17 -1
- package/src/config/index.js +13 -0
- 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 +230 -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 -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 -462
- 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 -0
- package/src/server/ejs-adapter.js +59 -59
- package/src/server/html-cache.js +1196 -1122
- package/src/server/image-optimizer.js +500 -407
- package/src/server/logs/access-middleware.js +66 -66
- package/src/server/logs/file-sink.js +193 -66
- package/src/server/logs/pipeline.js +165 -158
- 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 -100
- package/src/server/middleware/trailing-slash.js +53 -53
- package/src/server/middleware/upstream-proxy.js +141 -141
- package/src/server/og-image.js +356 -356
- package/src/server/port-guard.js +255 -255
- package/src/server/prewarm.js +1082 -1058
- package/src/server/redis.js +588 -569
- package/src/server/render.js +4 -4
- 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 +15 -1
- package/types/config/index.d.ts +8 -0
- package/types/server/cache-blob.d.ts +13 -0
- package/types/server/data-cache.d.ts +9 -0
- package/types/server/disk-cache.d.ts +36 -0
- package/types/server/html-cache.d.ts +26 -3
- package/types/server/logs/file-sink.d.ts +16 -5
- package/types/server/redis.d.ts +2 -1
|
@@ -1,158 +1,165 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Structured log pipeline: `log.subscribe` → kinds filtresi → file / S3.
|
|
3
|
-
*
|
|
4
|
-
* Sink yokken abone olunmaz: `emitLog` boş Set üzerinde döner ve stdout
|
|
5
|
-
* yoluna maliyet eklemez. Credential eksikse S3 açılmaz, site ayağa kalkar.
|
|
6
|
-
*/
|
|
7
|
-
import process from "node:process";
|
|
8
|
-
import * as log from "../../log.mjs";
|
|
9
|
-
import { readS3CredentialsFromEnv } from "../../config/index.js";
|
|
10
|
-
import { createFileSink } from "./file-sink.js";
|
|
11
|
-
import { createS3Sink } from "./s3-sink.js";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {import('../../config/index.js').LogsConfig} LogsConfig
|
|
15
|
-
* @typedef {import('../../config/index.js').ResolvedConfig} ResolvedConfig
|
|
16
|
-
* @typedef {import('./file-sink.js').LogSink} LogSink
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/** @type {(() => void) | null} */
|
|
20
|
-
let unsubscribe = null;
|
|
21
|
-
/** @type {LogSink[]} */
|
|
22
|
-
let sinks = [];
|
|
23
|
-
/** @type {Set<string>} */
|
|
24
|
-
let kindSet = new Set();
|
|
25
|
-
let accessMounted = false;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Access middleware mount edilmeli mi?
|
|
29
|
-
*
|
|
30
|
-
* Dev'de yalnızca console isteniyorsa mount edilmez — HTML satırlarını
|
|
31
|
-
* zaten devtools basıyor; çift kayıt olmasın. Sink açıksa ya da production
|
|
32
|
-
* console access log istiyorsa mount edilir.
|
|
33
|
-
*
|
|
34
|
-
* @param {LogsConfig} logs
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
export function shouldMountAccessLog(logs) {
|
|
38
|
-
if (!logs.kinds.includes("http")) return false;
|
|
39
|
-
if (logs.file.enabled || logs.s3.enabled) return true;
|
|
40
|
-
return logs.console && process.env.NODE_ENV !== "development";
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @param {ResolvedConfig} config
|
|
45
|
-
* @returns {Promise<{ accessLog: boolean }>}
|
|
46
|
-
*/
|
|
47
|
-
export async function configureLogs(config) {
|
|
48
|
-
await closeLogs();
|
|
49
|
-
|
|
50
|
-
const logs = config.logs;
|
|
51
|
-
kindSet = new Set(logs.kinds);
|
|
52
|
-
accessMounted = shouldMountAccessLog(logs);
|
|
53
|
-
|
|
54
|
-
log.configureLog({
|
|
55
|
-
console: logs.console,
|
|
56
|
-
// Access middleware HTTP'yi kendisi pipeline'a yazar; log.http yalnızca
|
|
57
|
-
// stdout için kalsın — aksi hâlde HTML istekleri (devtools) çiftlenir.
|
|
58
|
-
emitHttp: !accessMounted,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
/** @type {LogSink[]} */
|
|
62
|
-
const next = [];
|
|
63
|
-
|
|
64
|
-
if (logs.file.enabled) {
|
|
65
|
-
next.push(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
* @returns {Promise<void>}
|
|
146
|
-
*/
|
|
147
|
-
export async function
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Structured log pipeline: `log.subscribe` → kinds filtresi → file / S3.
|
|
3
|
+
*
|
|
4
|
+
* Sink yokken abone olunmaz: `emitLog` boş Set üzerinde döner ve stdout
|
|
5
|
+
* yoluna maliyet eklemez. Credential eksikse S3 açılmaz, site ayağa kalkar.
|
|
6
|
+
*/
|
|
7
|
+
import process from "node:process";
|
|
8
|
+
import * as log from "../../log.mjs";
|
|
9
|
+
import { readS3CredentialsFromEnv } from "../../config/index.js";
|
|
10
|
+
import { createFileSink } from "./file-sink.js";
|
|
11
|
+
import { createS3Sink } from "./s3-sink.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {import('../../config/index.js').LogsConfig} LogsConfig
|
|
15
|
+
* @typedef {import('../../config/index.js').ResolvedConfig} ResolvedConfig
|
|
16
|
+
* @typedef {import('./file-sink.js').LogSink} LogSink
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** @type {(() => void) | null} */
|
|
20
|
+
let unsubscribe = null;
|
|
21
|
+
/** @type {LogSink[]} */
|
|
22
|
+
let sinks = [];
|
|
23
|
+
/** @type {Set<string>} */
|
|
24
|
+
let kindSet = new Set();
|
|
25
|
+
let accessMounted = false;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Access middleware mount edilmeli mi?
|
|
29
|
+
*
|
|
30
|
+
* Dev'de yalnızca console isteniyorsa mount edilmez — HTML satırlarını
|
|
31
|
+
* zaten devtools basıyor; çift kayıt olmasın. Sink açıksa ya da production
|
|
32
|
+
* console access log istiyorsa mount edilir.
|
|
33
|
+
*
|
|
34
|
+
* @param {LogsConfig} logs
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
export function shouldMountAccessLog(logs) {
|
|
38
|
+
if (!logs.kinds.includes("http")) return false;
|
|
39
|
+
if (logs.file.enabled || logs.s3.enabled || logs.drainLog) return true;
|
|
40
|
+
return logs.console && process.env.NODE_ENV !== "development";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {ResolvedConfig} config
|
|
45
|
+
* @returns {Promise<{ accessLog: boolean }>}
|
|
46
|
+
*/
|
|
47
|
+
export async function configureLogs(config) {
|
|
48
|
+
await closeLogs();
|
|
49
|
+
|
|
50
|
+
const logs = config.logs;
|
|
51
|
+
kindSet = new Set(logs.kinds);
|
|
52
|
+
accessMounted = shouldMountAccessLog(logs);
|
|
53
|
+
|
|
54
|
+
log.configureLog({
|
|
55
|
+
console: logs.console,
|
|
56
|
+
// Access middleware HTTP'yi kendisi pipeline'a yazar; log.http yalnızca
|
|
57
|
+
// stdout için kalsın — aksi hâlde HTML istekleri (devtools) çiftlenir.
|
|
58
|
+
emitHttp: !accessMounted,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/** @type {LogSink[]} */
|
|
62
|
+
const next = [];
|
|
63
|
+
|
|
64
|
+
if (logs.file.enabled || logs.drainLog) {
|
|
65
|
+
next.push(
|
|
66
|
+
createFileSink({
|
|
67
|
+
root: config.root,
|
|
68
|
+
dir: logs.file.dir,
|
|
69
|
+
persist: logs.file.enabled,
|
|
70
|
+
drainLog: logs.drainLog,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (logs.s3.enabled) {
|
|
76
|
+
const credentials = readS3CredentialsFromEnv();
|
|
77
|
+
if (!logs.s3.bucket) {
|
|
78
|
+
console.warn(
|
|
79
|
+
"[logs] s3.enabled but no bucket (set JSKELET_LOG_BUCKET, JSKELET_S3_BUCKET or logs.s3.bucket)",
|
|
80
|
+
);
|
|
81
|
+
} else if (!credentials) {
|
|
82
|
+
console.warn(
|
|
83
|
+
"[logs] s3.enabled but credentials missing — set JSKELET_S3_ACCESS_KEY_ID and JSKELET_S3_SECRET_ACCESS_KEY",
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
86
|
+
const region = logs.s3.region || "auto";
|
|
87
|
+
next.push(
|
|
88
|
+
createS3Sink({
|
|
89
|
+
bucket: logs.s3.bucket,
|
|
90
|
+
prefix: logs.s3.prefix,
|
|
91
|
+
region,
|
|
92
|
+
endpoint: logs.s3.endpoint,
|
|
93
|
+
credentials,
|
|
94
|
+
flushIntervalMs: logs.s3.flushIntervalMs,
|
|
95
|
+
maxBatch: logs.s3.maxBatch,
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Redis satırıyla aynı kanal: console → jskelet dev `server` scope'una
|
|
100
|
+
// düşer. Credential basılmaz; yalnızca hedef konum.
|
|
101
|
+
const target = `${logs.s3.bucket}/${logs.s3.prefix}`.replace(/\/+/g, "/");
|
|
102
|
+
const via = logs.s3.endpoint ? ` @ ${logs.s3.endpoint}` : "";
|
|
103
|
+
console.log(`[logs] s3 connected — objects under \`${target}\`${via}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
sinks = next;
|
|
108
|
+
|
|
109
|
+
if (sinks.length) {
|
|
110
|
+
unsubscribe = log.subscribe((raw) => {
|
|
111
|
+
acceptLogEntry(raw);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { accessLog: accessMounted };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Access middleware ve `log.subscribe` ortak giriş noktası.
|
|
120
|
+
*
|
|
121
|
+
* @param {Record<string, unknown>} raw
|
|
122
|
+
*/
|
|
123
|
+
export function acceptLogEntry(raw) {
|
|
124
|
+
if (!sinks.length) return;
|
|
125
|
+
|
|
126
|
+
const kind = typeof raw.kind === "string" ? raw.kind : "event";
|
|
127
|
+
if (!kindSet.has(kind)) return;
|
|
128
|
+
|
|
129
|
+
const entry = {
|
|
130
|
+
...raw,
|
|
131
|
+
kind,
|
|
132
|
+
at: typeof raw.at === "number" ? raw.at : Date.now(),
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
for (const sink of sinks) {
|
|
136
|
+
void sink.write(entry).catch((error) => {
|
|
137
|
+
console.warn("[logs] sink write failed", error);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Kapanışta buffer'ları boşaltır.
|
|
144
|
+
*
|
|
145
|
+
* @returns {Promise<void>}
|
|
146
|
+
*/
|
|
147
|
+
export async function flushLogs() {
|
|
148
|
+
await Promise.all(sinks.map((sink) => sink.flush()));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @returns {Promise<void>}
|
|
153
|
+
*/
|
|
154
|
+
export async function closeLogs() {
|
|
155
|
+
if (unsubscribe) {
|
|
156
|
+
unsubscribe();
|
|
157
|
+
unsubscribe = null;
|
|
158
|
+
}
|
|
159
|
+
const closing = sinks;
|
|
160
|
+
sinks = [];
|
|
161
|
+
await Promise.all(closing.map((sink) => sink.close()));
|
|
162
|
+
kindSet = new Set();
|
|
163
|
+
accessMounted = false;
|
|
164
|
+
log.configureLog({ console: true, emitHttp: true });
|
|
165
|
+
}
|