jskelet 0.2.4 → 0.2.5

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.
Files changed (91) hide show
  1. package/AGENTS.md +132 -132
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -21
  4. package/bin/jskelet.mjs +103 -103
  5. package/docs/01-baslangic.md +285 -285
  6. package/docs/02-mimari.md +287 -287
  7. package/docs/03-routing.md +480 -480
  8. package/docs/04-render-ve-sablonlar.md +490 -490
  9. package/docs/05-islands.md +482 -482
  10. package/docs/06-cache.md +1209 -1209
  11. package/docs/08-build.md +366 -366
  12. package/docs/09-dev-araclari.md +335 -335
  13. package/docs/10-dagitim.md +329 -329
  14. package/docs/12-panel-ve-oturum.md +384 -384
  15. package/docs/README.md +105 -105
  16. package/docs/en/01-getting-started.md +292 -292
  17. package/docs/en/02-architecture.md +305 -305
  18. package/docs/en/03-routing.md +497 -497
  19. package/docs/en/04-rendering.md +504 -504
  20. package/docs/en/05-islands.md +492 -492
  21. package/docs/en/06-caching.md +1239 -1239
  22. package/docs/en/07-configuration.md +986 -986
  23. package/docs/en/08-build.md +383 -383
  24. package/docs/en/09-dev-tools.md +342 -342
  25. package/docs/en/10-deployment.md +332 -332
  26. package/docs/en/11-migration.md +359 -359
  27. package/docs/en/12-dashboards-and-sessions.md +392 -392
  28. package/docs/en/README.md +112 -112
  29. package/package.json +102 -102
  30. package/src/build/ensure-build.mjs +15 -15
  31. package/src/build/paths.mjs +143 -143
  32. package/src/build/resolve-peer.mjs +36 -36
  33. package/src/build/tasks/client.mjs +268 -268
  34. package/src/build/tasks/css.mjs +124 -124
  35. package/src/build/tasks/fonts.mjs +146 -146
  36. package/src/build/tasks/icons.mjs +224 -224
  37. package/src/build/tasks/images.mjs +244 -244
  38. package/src/build/tasks/precompress.mjs +78 -78
  39. package/src/client/cache-panel/i18n.js +670 -670
  40. package/src/client/cache-panel/login.html +74 -74
  41. package/src/client/cache-panel/panel.css +756 -756
  42. package/src/client/cache-panel/panel.html +308 -308
  43. package/src/client/cache-panel/panel.js +915 -915
  44. package/src/client/devtools/report.html +185 -185
  45. package/src/client/devtools/report.js +725 -725
  46. package/src/client/dom.js +95 -95
  47. package/src/client/form.js +192 -192
  48. package/src/client/index.js +35 -35
  49. package/src/client/registry.js +297 -297
  50. package/src/client/safe-image.js +91 -91
  51. package/src/client/store.js +36 -36
  52. package/src/client/swap.js +188 -188
  53. package/src/config/pattern.js +107 -107
  54. package/src/http/control-flow.js +71 -71
  55. package/src/http/cookies.js +257 -257
  56. package/src/http/request-cache.js +46 -46
  57. package/src/http/request-context.js +162 -162
  58. package/src/index.js +83 -83
  59. package/src/init.mjs +221 -221
  60. package/src/runtime/alias-hooks.mjs +119 -119
  61. package/src/runtime/register.mjs +4 -4
  62. package/src/server/assets.js +147 -147
  63. package/src/server/cache-deps.js +42 -42
  64. package/src/server/cache-panel.js +759 -759
  65. package/src/server/cloudflare.js +607 -595
  66. package/src/server/create-app.js +291 -291
  67. package/src/server/data-cache.js +462 -462
  68. package/src/server/dev/report.js +369 -369
  69. package/src/server/dev/socket.js +170 -170
  70. package/src/server/dev/version-check.mjs +139 -139
  71. package/src/server/html-cache.js +817 -817
  72. package/src/server/metadata.js +102 -102
  73. package/src/server/middleware/compression.js +205 -205
  74. package/src/server/middleware/csrf.js +134 -134
  75. package/src/server/middleware/dev-gate.js +62 -62
  76. package/src/server/middleware/headers.js +37 -37
  77. package/src/server/middleware/redirects.js +32 -32
  78. package/src/server/middleware/static-precompressed.js +100 -100
  79. package/src/server/middleware/upstream-proxy.js +141 -141
  80. package/src/server/prewarm.js +601 -601
  81. package/src/server/redis.js +569 -569
  82. package/src/server/router.js +128 -128
  83. package/src/server/status-page.js +164 -164
  84. package/src/server/upstream-limiter.js +376 -376
  85. package/src/server/upstream-tracking.js +166 -166
  86. package/src/start.mjs +7 -7
  87. package/src/templates/layout.ejs +44 -44
  88. package/src/version.mjs +31 -31
  89. package/src/views/components/loader.js +85 -85
  90. package/src/views/helpers/html.js +102 -102
  91. package/src/views/helpers/tags.js +245 -245
package/docs/en/README.md CHANGED
@@ -1,112 +1,112 @@
1
- # JSkelet documentation
2
-
3
- JSkelet is a framework that "feels frameworkless", built for SEO- and
4
- speed-focused sites: it produces complete HTML on the server with Express 5 +
5
- EJS, adds interactivity with vanilla JS islands, compiles CSS into a single
6
- stylesheet with Tailwind v4, and instead of ISR uses an HTML TTL cache that
7
- lives in process memory with stale-while-revalidate. No React, no TypeScript;
8
- plain JavaScript and JSDoc.
9
-
10
- This directory is the full reference for the framework. To read it in order,
11
- start from the beginning; if you are looking for a specific topic, go straight
12
- to the relevant entry.
13
-
14
- The Turkish edition of the same documents lives one directory up, in
15
- [`docs/`](../README.md). Both editions are kept in sync by hand, so if you
16
- change one, change the other.
17
-
18
- ## Read in order
19
-
20
- | Document | Topic |
21
- | --- | --- |
22
- | [01-getting-started.md](./01-getting-started.md) | Installation, `jskelet init`, first route, first island, directory structure, CLI commands |
23
- | [02-architecture.md](./02-architecture.md) | Architectural decisions and their rationale: the island model, complete server HTML, cache strategy, middleware order |
24
- | [03-routing.md](./03-routing.md) | The route module contract, load order, the controller contract, `ctx`, `notFound`/`redirect`, config redirects/rewrites |
25
- | [04-rendering.md](./04-rendering.md) | EJS layout, pages, automatic component registration, `html`/`tags` helpers, metadata → `<head>`, hooks |
26
- | [05-islands.md](./05-islands.md) | The `data-island` contract, hydration strategies, `client/entries/*`, `createStore`, DOM helpers, `startSafeImages` |
27
- | [06-caching.md](./06-caching.md) | `withHtmlCache`, `revalidate`, stale-while-revalidate, the cache key, `X-JSkelet-Cache`, in-request cache, degraded render, prewarm |
28
- | [07-configuration.md](./07-configuration.md) | Full `jskelet.config.mjs` reference, the `source` pattern syntax, environment variable table |
29
- | [08-build.md](./08-build.md) | The build pipeline, the manifest, hashed assets, CSS/Tailwind `@source`, fonts, icon sprite, image optimization, precompress |
30
- | [09-dev-tools.md](./09-dev-tools.md) | The `jskelet dev` flow, watch directories, CSS hot-swap, devtools overlay (Alt+D), the report page, the dev gate |
31
- | [10-deployment.md](./10-deployment.md) | Prod build + start, environment variables, Docker, reverse proxy, health check |
32
- | [11-migration.md](./11-migration.md) | Migrating from Next.js: the equivalence table and a step-by-step plan |
33
- | [12-dashboards-and-sessions.md](./12-dashboards-and-sessions.md) | Per-visitor pages: `private: true`, signed cookie sessions, CSRF, `fragment()`, swapping regions and the form loop |
34
-
35
- ## Quick access by topic
36
-
37
- - **How do I add a page?** → [03-routing.md](./03-routing.md) and
38
- [04-rendering.md](./04-rendering.md)
39
- - **I want something to happen when a button is clicked** →
40
- [05-islands.md](./05-islands.md)
41
- - **Why is the page returning `MISS` / why am I seeing stale data?** →
42
- [06-caching.md](./06-caching.md)
43
- - **How do I write a page that depends on the session?** →
44
- [12-dashboards-and-sessions.md](./12-dashboards-and-sessions.md)
45
- - **What does each config field do?** → [07-configuration.md](./07-configuration.md)
46
- - **Styles are missing / icons don't show up** → [08-build.md](./08-build.md)
47
- - **Going live** → [10-deployment.md](./10-deployment.md)
48
-
49
- ## Runnable examples
50
-
51
- All four are in working order; most of the examples in the docs were taken from
52
- them.
53
-
54
- **`examples/minimal/`** — two routes, one component, one island, minimal config.
55
- The smallest working form of the framework.
56
-
57
- ```bash
58
- npm --prefix examples/minimal install
59
- npm --prefix examples/minimal run dev
60
- ```
61
-
62
- **`examples/blog/`** — a dynamic route (`/blog/:slug`), tag pages, the whole of
63
- the `redirects`/`rewrites`/`headers`/`cache` configuration, tab panels arriving
64
- as fragments, form submission, prewarm,
65
- `robots.txt`/`sitemap.xml`/`rss.xml` and four islands (theme, tabs, search,
66
- form).
67
-
68
- ```bash
69
- npm --prefix examples/blog install
70
- npm --prefix examples/blog run dev
71
- ```
72
-
73
- **`examples/marketing/`** — the framework's own marketing site: hero, comparison
74
- table, live latency measurement, FAQ, docs index, release notes and a download
75
- page. The byte counts on the page are read in `lib/payload.js` from the site's
76
- **own** build output, and the release info in `lib/release.js` from the
77
- installed package's `package.json`; the latency numbers are measured in the
78
- browser by the `latency` island. With a long TTL (one hour) and a prewarm that
79
- warms every page, it shows the profile in which the cache works most
80
- efficiently.
81
-
82
- It also serves **these documents**: `/docs/<chapter>` reads the markdown files
83
- in `node_modules/jskelet/docs/` and renders them with a sidebar, an "on this
84
- page" list and sequential navigation. The renderer is a small module in
85
- `lib/markdown.js` — no dependency — and the source of truth stays the package,
86
- so the site never drifts from the installed version.
87
-
88
- The site is also **bilingual**: English by default at the root, Turkish under
89
- `/tr`, with the same route names in both languages. There is no i18n in the
90
- framework; language resolution lives in `lib/i18n.js` as the application's own
91
- contract and is wired to a dictionary via `hooks.layoutContext`. This is the
92
- place to look if you want to see how to build a multilingual site with this
93
- surface.
94
-
95
- ```bash
96
- npm --prefix examples/marketing install
97
- npm --prefix examples/marketing run dev
98
- ```
99
-
100
- **`examples/dashboard/`** — the opposite axis from the other three: per-visitor
101
- pages. Sign-in with a signed cookie session, a `private: true` protected panel,
102
- a paginated table fragment, a CSRF-protected mutation form and an island that
103
- returns a cleanup function. It also has a public landing page, so a cached
104
- response and a `no-store` one sit side by side in the same application.
105
-
106
- ```bash
107
- npm --prefix examples/dashboard install
108
- npm --prefix examples/dashboard run dev
109
- ```
110
-
111
- In all four examples, `node smoke.mjs` verifies that the endpoints respond as
112
- expected while the server is up.
1
+ # JSkelet documentation
2
+
3
+ JSkelet is a framework that "feels frameworkless", built for SEO- and
4
+ speed-focused sites: it produces complete HTML on the server with Express 5 +
5
+ EJS, adds interactivity with vanilla JS islands, compiles CSS into a single
6
+ stylesheet with Tailwind v4, and instead of ISR uses an HTML TTL cache that
7
+ lives in process memory with stale-while-revalidate. No React, no TypeScript;
8
+ plain JavaScript and JSDoc.
9
+
10
+ This directory is the full reference for the framework. To read it in order,
11
+ start from the beginning; if you are looking for a specific topic, go straight
12
+ to the relevant entry.
13
+
14
+ The Turkish edition of the same documents lives one directory up, in
15
+ [`docs/`](../README.md). Both editions are kept in sync by hand, so if you
16
+ change one, change the other.
17
+
18
+ ## Read in order
19
+
20
+ | Document | Topic |
21
+ | --- | --- |
22
+ | [01-getting-started.md](./01-getting-started.md) | Installation, `jskelet init`, first route, first island, directory structure, CLI commands |
23
+ | [02-architecture.md](./02-architecture.md) | Architectural decisions and their rationale: the island model, complete server HTML, cache strategy, middleware order |
24
+ | [03-routing.md](./03-routing.md) | The route module contract, load order, the controller contract, `ctx`, `notFound`/`redirect`, config redirects/rewrites |
25
+ | [04-rendering.md](./04-rendering.md) | EJS layout, pages, automatic component registration, `html`/`tags` helpers, metadata → `<head>`, hooks |
26
+ | [05-islands.md](./05-islands.md) | The `data-island` contract, hydration strategies, `client/entries/*`, `createStore`, DOM helpers, `startSafeImages` |
27
+ | [06-caching.md](./06-caching.md) | `withHtmlCache`, `revalidate`, stale-while-revalidate, the cache key, `X-JSkelet-Cache`, in-request cache, degraded render, prewarm |
28
+ | [07-configuration.md](./07-configuration.md) | Full `jskelet.config.mjs` reference, the `source` pattern syntax, environment variable table |
29
+ | [08-build.md](./08-build.md) | The build pipeline, the manifest, hashed assets, CSS/Tailwind `@source`, fonts, icon sprite, image optimization, precompress |
30
+ | [09-dev-tools.md](./09-dev-tools.md) | The `jskelet dev` flow, watch directories, CSS hot-swap, devtools overlay (Alt+D), the report page, the dev gate |
31
+ | [10-deployment.md](./10-deployment.md) | Prod build + start, environment variables, Docker, reverse proxy, health check |
32
+ | [11-migration.md](./11-migration.md) | Migrating from Next.js: the equivalence table and a step-by-step plan |
33
+ | [12-dashboards-and-sessions.md](./12-dashboards-and-sessions.md) | Per-visitor pages: `private: true`, signed cookie sessions, CSRF, `fragment()`, swapping regions and the form loop |
34
+
35
+ ## Quick access by topic
36
+
37
+ - **How do I add a page?** → [03-routing.md](./03-routing.md) and
38
+ [04-rendering.md](./04-rendering.md)
39
+ - **I want something to happen when a button is clicked** →
40
+ [05-islands.md](./05-islands.md)
41
+ - **Why is the page returning `MISS` / why am I seeing stale data?** →
42
+ [06-caching.md](./06-caching.md)
43
+ - **How do I write a page that depends on the session?** →
44
+ [12-dashboards-and-sessions.md](./12-dashboards-and-sessions.md)
45
+ - **What does each config field do?** → [07-configuration.md](./07-configuration.md)
46
+ - **Styles are missing / icons don't show up** → [08-build.md](./08-build.md)
47
+ - **Going live** → [10-deployment.md](./10-deployment.md)
48
+
49
+ ## Runnable examples
50
+
51
+ All four are in working order; most of the examples in the docs were taken from
52
+ them.
53
+
54
+ **`examples/minimal/`** — two routes, one component, one island, minimal config.
55
+ The smallest working form of the framework.
56
+
57
+ ```bash
58
+ npm --prefix examples/minimal install
59
+ npm --prefix examples/minimal run dev
60
+ ```
61
+
62
+ **`examples/blog/`** — a dynamic route (`/blog/:slug`), tag pages, the whole of
63
+ the `redirects`/`rewrites`/`headers`/`cache` configuration, tab panels arriving
64
+ as fragments, form submission, prewarm,
65
+ `robots.txt`/`sitemap.xml`/`rss.xml` and four islands (theme, tabs, search,
66
+ form).
67
+
68
+ ```bash
69
+ npm --prefix examples/blog install
70
+ npm --prefix examples/blog run dev
71
+ ```
72
+
73
+ **`examples/marketing/`** — the framework's own marketing site: hero, comparison
74
+ table, live latency measurement, FAQ, docs index, release notes and a download
75
+ page. The byte counts on the page are read in `lib/payload.js` from the site's
76
+ **own** build output, and the release info in `lib/release.js` from the
77
+ installed package's `package.json`; the latency numbers are measured in the
78
+ browser by the `latency` island. With a long TTL (one hour) and a prewarm that
79
+ warms every page, it shows the profile in which the cache works most
80
+ efficiently.
81
+
82
+ It also serves **these documents**: `/docs/<chapter>` reads the markdown files
83
+ in `node_modules/jskelet/docs/` and renders them with a sidebar, an "on this
84
+ page" list and sequential navigation. The renderer is a small module in
85
+ `lib/markdown.js` — no dependency — and the source of truth stays the package,
86
+ so the site never drifts from the installed version.
87
+
88
+ The site is also **bilingual**: English by default at the root, Turkish under
89
+ `/tr`, with the same route names in both languages. There is no i18n in the
90
+ framework; language resolution lives in `lib/i18n.js` as the application's own
91
+ contract and is wired to a dictionary via `hooks.layoutContext`. This is the
92
+ place to look if you want to see how to build a multilingual site with this
93
+ surface.
94
+
95
+ ```bash
96
+ npm --prefix examples/marketing install
97
+ npm --prefix examples/marketing run dev
98
+ ```
99
+
100
+ **`examples/dashboard/`** — the opposite axis from the other three: per-visitor
101
+ pages. Sign-in with a signed cookie session, a `private: true` protected panel,
102
+ a paginated table fragment, a CSRF-protected mutation form and an island that
103
+ returns a cleanup function. It also has a public landing page, so a cached
104
+ response and a `no-store` one sit side by side in the same application.
105
+
106
+ ```bash
107
+ npm --prefix examples/dashboard install
108
+ npm --prefix examples/dashboard run dev
109
+ ```
110
+
111
+ In all four examples, `node smoke.mjs` verifies that the endpoints respond as
112
+ expected while the server is up.
package/package.json CHANGED
@@ -1,103 +1,103 @@
1
- {
2
- "name": "jskelet",
3
- "version": "0.2.4",
4
- "description": "A framework that feels like no framework: Express 5 + EJS server rendering, vanilla JS islands, Tailwind v4 and an in-process HTML TTL cache.",
5
- "type": "module",
6
- "license": "MIT",
7
- "author": "Ayberk Enis",
8
- "homepage": "https://github.com/ayberkenis/jskelet#readme",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/ayberkenis/jskelet.git"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/ayberkenis/jskelet/issues"
15
- },
16
- "keywords": [
17
- "ssr",
18
- "islands",
19
- "express",
20
- "ejs",
21
- "esbuild",
22
- "tailwind",
23
- "seo",
24
- "isr"
25
- ],
26
- "bin": {
27
- "jskelet": "./bin/jskelet.mjs"
28
- },
29
- "main": "./src/index.js",
30
- "exports": {
31
- ".": "./src/index.js",
32
- "./server": "./src/index.js",
33
- "./client": "./src/client/index.js",
34
- "./html": "./src/views/helpers/html.js",
35
- "./tags": "./src/views/helpers/tags.js",
36
- "./cookies": "./src/http/cookies.js",
37
- "./log": "./src/log.mjs",
38
- "./register": "./src/runtime/register.mjs",
39
- "./layout": "./src/templates/layout.ejs"
40
- },
41
- "files": [
42
- "bin",
43
- "src",
44
- "docs",
45
- "README.md",
46
- "AGENTS.md",
47
- "CHANGELOG.md",
48
- "LICENSE"
49
- ],
50
- "engines": {
51
- "node": ">=22"
52
- },
53
- "scripts": {
54
- "lint": "eslint",
55
- "test": "node --test \"test/**/*.test.mjs\"",
56
- "example:minimal": "npm --prefix examples/minimal run dev",
57
- "example:blog": "npm --prefix examples/blog run dev",
58
- "example:dashboard": "npm --prefix examples/dashboard run dev"
59
- },
60
- "dependencies": {
61
- "ejs": "^6.0.1",
62
- "esbuild": "^0.28.2",
63
- "express": "^5.2.1",
64
- "tailwind-merge": "^3.5.0"
65
- },
66
- "peerDependencies": {
67
- "@phosphor-icons/core": "^2.1.1",
68
- "@tailwindcss/postcss": "^4.3.3",
69
- "ioredis": "^5.4.0 || ^6.0.0",
70
- "lightningcss": "^1.32.0",
71
- "postcss": "^8.5.26",
72
- "sharp": "^0.35.4",
73
- "tailwindcss": "^4.3.3"
74
- },
75
- "peerDependenciesMeta": {
76
- "@phosphor-icons/core": {
77
- "optional": true
78
- },
79
- "@tailwindcss/postcss": {
80
- "optional": true
81
- },
82
- "ioredis": {
83
- "optional": true
84
- },
85
- "lightningcss": {
86
- "optional": true
87
- },
88
- "postcss": {
89
- "optional": true
90
- },
91
- "sharp": {
92
- "optional": true
93
- },
94
- "tailwindcss": {
95
- "optional": true
96
- }
97
- },
98
- "devDependencies": {
99
- "@eslint/js": "^9",
100
- "eslint": "^9",
101
- "globals": "^16"
102
- }
1
+ {
2
+ "name": "jskelet",
3
+ "version": "0.2.5",
4
+ "description": "A framework that feels like no framework: Express 5 + EJS server rendering, vanilla JS islands, Tailwind v4 and an in-process HTML TTL cache.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Ayberk Enis",
8
+ "homepage": "https://github.com/ayberkenis/jskelet#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/ayberkenis/jskelet.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/ayberkenis/jskelet/issues"
15
+ },
16
+ "keywords": [
17
+ "ssr",
18
+ "islands",
19
+ "express",
20
+ "ejs",
21
+ "esbuild",
22
+ "tailwind",
23
+ "seo",
24
+ "isr"
25
+ ],
26
+ "bin": {
27
+ "jskelet": "./bin/jskelet.mjs"
28
+ },
29
+ "main": "./src/index.js",
30
+ "exports": {
31
+ ".": "./src/index.js",
32
+ "./server": "./src/index.js",
33
+ "./client": "./src/client/index.js",
34
+ "./html": "./src/views/helpers/html.js",
35
+ "./tags": "./src/views/helpers/tags.js",
36
+ "./cookies": "./src/http/cookies.js",
37
+ "./log": "./src/log.mjs",
38
+ "./register": "./src/runtime/register.mjs",
39
+ "./layout": "./src/templates/layout.ejs"
40
+ },
41
+ "files": [
42
+ "bin",
43
+ "src",
44
+ "docs",
45
+ "README.md",
46
+ "AGENTS.md",
47
+ "CHANGELOG.md",
48
+ "LICENSE"
49
+ ],
50
+ "engines": {
51
+ "node": ">=22"
52
+ },
53
+ "scripts": {
54
+ "lint": "eslint",
55
+ "test": "node --test \"test/**/*.test.mjs\"",
56
+ "example:minimal": "npm --prefix examples/minimal run dev",
57
+ "example:blog": "npm --prefix examples/blog run dev",
58
+ "example:dashboard": "npm --prefix examples/dashboard run dev"
59
+ },
60
+ "dependencies": {
61
+ "ejs": "^6.0.1",
62
+ "esbuild": "^0.28.2",
63
+ "express": "^5.2.1",
64
+ "tailwind-merge": "^3.5.0"
65
+ },
66
+ "peerDependencies": {
67
+ "@phosphor-icons/core": "^2.1.1",
68
+ "@tailwindcss/postcss": "^4.3.3",
69
+ "ioredis": "^5.4.0 || ^6.0.0",
70
+ "lightningcss": "^1.32.0",
71
+ "postcss": "^8.5.26",
72
+ "sharp": "^0.35.4",
73
+ "tailwindcss": "^4.3.3"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "@phosphor-icons/core": {
77
+ "optional": true
78
+ },
79
+ "@tailwindcss/postcss": {
80
+ "optional": true
81
+ },
82
+ "ioredis": {
83
+ "optional": true
84
+ },
85
+ "lightningcss": {
86
+ "optional": true
87
+ },
88
+ "postcss": {
89
+ "optional": true
90
+ },
91
+ "sharp": {
92
+ "optional": true
93
+ },
94
+ "tailwindcss": {
95
+ "optional": true
96
+ }
97
+ },
98
+ "devDependencies": {
99
+ "@eslint/js": "^9",
100
+ "eslint": "^9",
101
+ "globals": "^16"
102
+ }
103
103
  }
@@ -1,15 +1,15 @@
1
- /**
2
- * `jskelet start` öncesi çalışır: build çıktısı yoksa üretir.
3
- *
4
- * Docker imajında build zaten yapıldığı için bu bir no-op; amaç `npm start`ı
5
- * doğrudan çalıştıran birinin stilsiz bir sayfayla karşılaşmaması.
6
- */
7
- import fs from "node:fs";
8
- import path from "node:path";
9
- import { loadConfig } from "../config/index.js";
10
-
11
- const config = await loadConfig();
12
-
13
- if (!fs.existsSync(path.join(config.dirs.generated, "manifest.json"))) {
14
- await import("./build.mjs");
15
- }
1
+ /**
2
+ * `jskelet start` öncesi çalışır: build çıktısı yoksa üretir.
3
+ *
4
+ * Docker imajında build zaten yapıldığı için bu bir no-op; amaç `npm start`ı
5
+ * doğrudan çalıştıran birinin stilsiz bir sayfayla karşılaşmaması.
6
+ */
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import { loadConfig } from "../config/index.js";
10
+
11
+ const config = await loadConfig();
12
+
13
+ if (!fs.existsSync(path.join(config.dirs.generated, "manifest.json"))) {
14
+ await import("./build.mjs");
15
+ }