@docubook/flame 1.6.0 → 1.6.2
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/.docu/lib/build.deno.js +3 -3
- package/.docu/lib/{build.impl-N2MBT3CM.js → build.impl-CFTUVIX7.js} +3 -3
- package/.docu/lib/build.node.js +3 -3
- package/.docu/lib/{chunk-ZA5QB5UK.js → chunk-77NNQDFX.js} +2 -2
- package/.docu/lib/{chunk-TI6M4643.js → chunk-KHRQUSNL.js} +178 -111
- package/.docu/lib/{chunk-UUS45SUC.js → chunk-N25ZVCKO.js} +1 -1
- package/.docu/lib/{chunk-JTH4JBBS.js → chunk-OREEWUOV.js} +2 -2
- package/.docu/lib/{chunk-Y2TAEAUQ.js → chunk-TU7G4RJV.js} +1 -1
- package/.docu/lib/{chunk-IJFMQFWW.js → chunk-WSJC3PRH.js} +31 -28
- package/.docu/lib/clean.js +1 -1
- package/.docu/lib/deploy.deno.js +1 -1
- package/.docu/lib/deploy.node.js +1 -1
- package/.docu/lib/preview.deno.js +2 -2
- package/.docu/lib/preview.node.js +2 -2
- package/.docu/lib/server.deno.js +3 -3
- package/.docu/lib/server.node.js +3 -3
- package/.docu/node/client-routes.ts +4 -2
- package/.docu/node/deploy.shared.ts +197 -111
- package/.docu/node/deploy.ts +3 -57
- package/.docu/node/hydrate.node.ts +14 -4
- package/.docu/node/hydrate.ts +14 -4
- package/bin/compile-lib.mjs +0 -24
- package/package.json +3 -3
package/.docu/lib/build.deno.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuildCli
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-OREEWUOV.js";
|
|
4
|
+
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-TU7G4RJV.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/build.deno.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
runBuildCli
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-OREEWUOV.js";
|
|
5
|
+
import "./chunk-WSJC3PRH.js";
|
|
6
6
|
import "./chunk-EOK6KATZ.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-TU7G4RJV.js";
|
|
8
8
|
import "./chunk-4IQXHHPF.js";
|
|
9
9
|
export {
|
|
10
10
|
runBuild,
|
package/.docu/lib/build.node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuildCli
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-OREEWUOV.js";
|
|
4
|
+
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-TU7G4RJV.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/build.node.ts
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
htmlShell,
|
|
15
15
|
initSentry,
|
|
16
16
|
loadPlugins
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-WSJC3PRH.js";
|
|
18
18
|
import {
|
|
19
19
|
SECURITY_HEADERS,
|
|
20
20
|
generateNonce,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./chunk-EOK6KATZ.js";
|
|
28
28
|
import {
|
|
29
29
|
logger
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-TU7G4RJV.js";
|
|
31
31
|
import {
|
|
32
32
|
DIST_DIR,
|
|
33
33
|
DOCS_DIR,
|
|
@@ -9,6 +9,98 @@ import { existsSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
var WORKFLOW_DIR = join(PROJECT_ROOT, ".github/workflows");
|
|
11
11
|
var WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy.yml");
|
|
12
|
+
var NGINX_CONF = `server {
|
|
13
|
+
listen 80;
|
|
14
|
+
server_name _;
|
|
15
|
+
root /usr/share/nginx/html;
|
|
16
|
+
index index.html;
|
|
17
|
+
|
|
18
|
+
gzip on;
|
|
19
|
+
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
20
|
+
|
|
21
|
+
# Security headers (HSTS effective when HTTPS is terminated upstream)
|
|
22
|
+
add_header X-Frame-Options "DENY" always;
|
|
23
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
24
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
25
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
26
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
27
|
+
|
|
28
|
+
location /assets/ {
|
|
29
|
+
expires 1y;
|
|
30
|
+
add_header Cache-Control "public, immutable";
|
|
31
|
+
add_header X-Frame-Options "DENY" always;
|
|
32
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
33
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
34
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
35
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
location /docs/assets/ {
|
|
39
|
+
expires 7d;
|
|
40
|
+
add_header Cache-Control "public";
|
|
41
|
+
add_header X-Frame-Options "DENY" always;
|
|
42
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
43
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
44
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
45
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
location / {
|
|
49
|
+
try_files $uri $uri.html $uri/ =404;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
var DOCKERIGNORE = `node_modules
|
|
54
|
+
.git
|
|
55
|
+
*.DS_Store
|
|
56
|
+
.docu/dist
|
|
57
|
+
.docu/lib
|
|
58
|
+
.env
|
|
59
|
+
.env.*
|
|
60
|
+
.npmrc
|
|
61
|
+
*.log
|
|
62
|
+
`;
|
|
63
|
+
function detectPkgManager(dir) {
|
|
64
|
+
const bunLockFile = existsSync(join(dir, "bun.lock")) ? "bun.lock" : existsSync(join(dir, "bun.lockb")) ? "bun.lockb" : null;
|
|
65
|
+
if (bunLockFile) {
|
|
66
|
+
return {
|
|
67
|
+
baseImage: "oven/bun:1",
|
|
68
|
+
lockFile: bunLockFile,
|
|
69
|
+
installCmd: "bun install --frozen-lockfile",
|
|
70
|
+
runCmd: "bun",
|
|
71
|
+
cache: "",
|
|
72
|
+
setupAction: "bun"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (existsSync(join(dir, "pnpm-lock.yaml"))) {
|
|
76
|
+
return {
|
|
77
|
+
baseImage: "node:22-alpine",
|
|
78
|
+
lockFile: "pnpm-lock.yaml",
|
|
79
|
+
installCmd: "corepack enable && pnpm install --frozen-lockfile",
|
|
80
|
+
runCmd: "pnpm",
|
|
81
|
+
cache: "pnpm",
|
|
82
|
+
setupAction: "pnpm"
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (existsSync(join(dir, "yarn.lock"))) {
|
|
86
|
+
return {
|
|
87
|
+
baseImage: "node:22-alpine",
|
|
88
|
+
lockFile: "yarn.lock",
|
|
89
|
+
installCmd: "yarn install --frozen-lockfile",
|
|
90
|
+
runCmd: "yarn",
|
|
91
|
+
cache: "yarn",
|
|
92
|
+
setupAction: "node"
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
baseImage: "node:22-alpine",
|
|
97
|
+
lockFile: "package-lock.json",
|
|
98
|
+
installCmd: "npm ci",
|
|
99
|
+
runCmd: "npm",
|
|
100
|
+
cache: "npm",
|
|
101
|
+
setupAction: "node"
|
|
102
|
+
};
|
|
103
|
+
}
|
|
12
104
|
var HEADERS_FILE = `/*
|
|
13
105
|
X-Frame-Options: DENY
|
|
14
106
|
X-Content-Type-Options: nosniff
|
|
@@ -35,20 +127,21 @@ async function runBuild() {
|
|
|
35
127
|
process.env.FLAME_BUILD_SILENT = "1";
|
|
36
128
|
process.env.LOG_LEVEL = "error";
|
|
37
129
|
}
|
|
38
|
-
const { runBuildCli } = await import("./build.impl-
|
|
130
|
+
const { runBuildCli } = await import("./build.impl-CFTUVIX7.js");
|
|
39
131
|
await runBuildCli();
|
|
40
132
|
}
|
|
41
133
|
async function writeDockerFiles() {
|
|
42
134
|
const dockerDir = PROJECT_ROOT;
|
|
135
|
+
const pm = detectPkgManager(dockerDir);
|
|
43
136
|
if (!existsSync(join(dockerDir, "Dockerfile"))) {
|
|
44
137
|
await writeFile(
|
|
45
138
|
join(dockerDir, "Dockerfile"),
|
|
46
|
-
`FROM
|
|
139
|
+
`FROM ${pm.baseImage} AS builder
|
|
47
140
|
WORKDIR /app
|
|
48
|
-
COPY package.json
|
|
49
|
-
RUN
|
|
141
|
+
COPY package.json ${pm.lockFile} ./
|
|
142
|
+
RUN ${pm.installCmd}
|
|
50
143
|
COPY . .
|
|
51
|
-
RUN
|
|
144
|
+
RUN ${pm.runCmd} run build
|
|
52
145
|
|
|
53
146
|
FROM nginx:alpine
|
|
54
147
|
COPY --from=builder /app/.docu/dist /usr/share/nginx/html
|
|
@@ -61,73 +154,96 @@ CMD ["nginx", "-g", "daemon off;"]
|
|
|
61
154
|
log.created("\u{1F4C4} Created Dockerfile");
|
|
62
155
|
}
|
|
63
156
|
if (!existsSync(join(dockerDir, "nginx.conf"))) {
|
|
64
|
-
await writeFile(
|
|
65
|
-
|
|
66
|
-
`server {
|
|
67
|
-
listen 80;
|
|
68
|
-
server_name _;
|
|
69
|
-
root /usr/share/nginx/html;
|
|
70
|
-
index index.html;
|
|
71
|
-
|
|
72
|
-
gzip on;
|
|
73
|
-
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
74
|
-
|
|
75
|
-
# Security headers (HSTS effective when HTTPS is terminated upstream)
|
|
76
|
-
add_header X-Frame-Options "DENY" always;
|
|
77
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
78
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
79
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
80
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
81
|
-
|
|
82
|
-
location /assets/ {
|
|
83
|
-
expires 1y;
|
|
84
|
-
add_header Cache-Control "public, immutable";
|
|
85
|
-
add_header X-Frame-Options "DENY" always;
|
|
86
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
87
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
88
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
89
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
location /docs/assets/ {
|
|
93
|
-
expires 7d;
|
|
94
|
-
add_header Cache-Control "public";
|
|
95
|
-
add_header X-Frame-Options "DENY" always;
|
|
96
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
97
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
98
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
99
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
157
|
+
await writeFile(join(dockerDir, "nginx.conf"), NGINX_CONF);
|
|
158
|
+
log.created("\u{1F4C4} Created nginx.conf");
|
|
100
159
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
160
|
+
if (!existsSync(join(dockerDir, ".dockerignore"))) {
|
|
161
|
+
await writeFile(join(dockerDir, ".dockerignore"), DOCKERIGNORE);
|
|
162
|
+
log.created("\u{1F4C4} Created .dockerignore");
|
|
104
163
|
}
|
|
105
164
|
}
|
|
106
|
-
|
|
165
|
+
function generateWorkflowYml() {
|
|
166
|
+
const pm = detectPkgManager(PROJECT_ROOT);
|
|
167
|
+
const setupSteps = [
|
|
168
|
+
" - uses: actions/checkout@v7",
|
|
169
|
+
" with:",
|
|
170
|
+
" fetch-depth: 0",
|
|
171
|
+
""
|
|
172
|
+
];
|
|
173
|
+
if (pm.setupAction === "bun") {
|
|
174
|
+
setupSteps.push(
|
|
175
|
+
" - uses: oven-sh/setup-bun@v2",
|
|
176
|
+
" with:",
|
|
177
|
+
" bun-version: latest",
|
|
178
|
+
""
|
|
107
179
|
);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
180
|
+
} else if (pm.setupAction === "pnpm") {
|
|
181
|
+
setupSteps.push(
|
|
182
|
+
" - uses: pnpm/action-setup@v6",
|
|
183
|
+
"",
|
|
184
|
+
" - uses: actions/setup-node@v6",
|
|
185
|
+
" with:",
|
|
186
|
+
" node-version: 22",
|
|
187
|
+
` cache: ${pm.cache}`,
|
|
188
|
+
""
|
|
189
|
+
);
|
|
190
|
+
} else {
|
|
191
|
+
setupSteps.push(
|
|
192
|
+
" - uses: actions/setup-node@v6",
|
|
193
|
+
" with:",
|
|
194
|
+
" node-version: 22",
|
|
195
|
+
` cache: ${pm.cache}`,
|
|
196
|
+
""
|
|
123
197
|
);
|
|
124
|
-
log.created("\u{1F4C4} Created .dockerignore");
|
|
125
198
|
}
|
|
199
|
+
return [
|
|
200
|
+
`name: Deploy to GitHub Pages`,
|
|
201
|
+
"",
|
|
202
|
+
"on:",
|
|
203
|
+
" push:",
|
|
204
|
+
" branches: [main]",
|
|
205
|
+
" workflow_dispatch:",
|
|
206
|
+
"",
|
|
207
|
+
"permissions:",
|
|
208
|
+
" contents: read",
|
|
209
|
+
" pages: write",
|
|
210
|
+
" id-token: write",
|
|
211
|
+
"",
|
|
212
|
+
"concurrency:",
|
|
213
|
+
' group: "pages"',
|
|
214
|
+
" cancel-in-progress: false",
|
|
215
|
+
"",
|
|
216
|
+
"jobs:",
|
|
217
|
+
" build:",
|
|
218
|
+
" runs-on: ubuntu-latest",
|
|
219
|
+
" steps:",
|
|
220
|
+
...setupSteps,
|
|
221
|
+
` - run: ${pm.installCmd}`,
|
|
222
|
+
"",
|
|
223
|
+
` - run: ${pm.runCmd} run build`,
|
|
224
|
+
"",
|
|
225
|
+
" - name: Add .nojekyll",
|
|
226
|
+
" run: touch .docu/dist/.nojekyll",
|
|
227
|
+
"",
|
|
228
|
+
" - uses: actions/upload-pages-artifact@v3",
|
|
229
|
+
" with:",
|
|
230
|
+
" path: .docu/dist",
|
|
231
|
+
"",
|
|
232
|
+
" deploy:",
|
|
233
|
+
" environment:",
|
|
234
|
+
" name: github-pages",
|
|
235
|
+
" url: ${{ steps.deployment.outputs.page_url }}",
|
|
236
|
+
" runs-on: ubuntu-latest",
|
|
237
|
+
" needs: build",
|
|
238
|
+
" steps:",
|
|
239
|
+
" - id: deployment",
|
|
240
|
+
" uses: actions/deploy-pages@v4"
|
|
241
|
+
].join("\n");
|
|
126
242
|
}
|
|
127
243
|
async function writeGhaWorkflow() {
|
|
128
244
|
if (!existsSync(WORKFLOW_FILE)) {
|
|
129
245
|
await mkdir(WORKFLOW_DIR, { recursive: true });
|
|
130
|
-
await writeFile(WORKFLOW_FILE,
|
|
246
|
+
await writeFile(WORKFLOW_FILE, generateWorkflowYml());
|
|
131
247
|
log.created("\u{1F4C4} Created .github/workflows/deploy.yml");
|
|
132
248
|
}
|
|
133
249
|
}
|
|
@@ -149,55 +265,6 @@ async function runDeploy() {
|
|
|
149
265
|
log.out(" Push to GitHub and enable Pages (Settings \u2192 Pages \u2192 Source: GitHub Actions)");
|
|
150
266
|
}
|
|
151
267
|
}
|
|
152
|
-
var GITHUB_ACTIONS_WORKFLOW = `name: Deploy to GitHub Pages
|
|
153
|
-
|
|
154
|
-
on:
|
|
155
|
-
push:
|
|
156
|
-
branches: [main]
|
|
157
|
-
workflow_dispatch:
|
|
158
|
-
|
|
159
|
-
permissions:
|
|
160
|
-
contents: read
|
|
161
|
-
pages: write
|
|
162
|
-
id-token: write
|
|
163
|
-
|
|
164
|
-
concurrency:
|
|
165
|
-
group: "pages"
|
|
166
|
-
cancel-in-progress: false
|
|
167
|
-
|
|
168
|
-
jobs:
|
|
169
|
-
build:
|
|
170
|
-
runs-on: ubuntu-latest
|
|
171
|
-
steps:
|
|
172
|
-
- uses: actions/checkout@v4
|
|
173
|
-
with:
|
|
174
|
-
fetch-depth: 0
|
|
175
|
-
|
|
176
|
-
- uses: actions/setup-node@v4
|
|
177
|
-
with:
|
|
178
|
-
node-version: 22
|
|
179
|
-
|
|
180
|
-
- run: npm install
|
|
181
|
-
|
|
182
|
-
- run: npm run build
|
|
183
|
-
|
|
184
|
-
- name: Add .nojekyll
|
|
185
|
-
run: touch .docu/dist/.nojekyll
|
|
186
|
-
|
|
187
|
-
- uses: actions/upload-pages-artifact@v3
|
|
188
|
-
with:
|
|
189
|
-
path: .docu/dist
|
|
190
|
-
|
|
191
|
-
deploy:
|
|
192
|
-
environment:
|
|
193
|
-
name: github-pages
|
|
194
|
-
url: \${{ steps.deployment.outputs.page_url }}
|
|
195
|
-
runs-on: ubuntu-latest
|
|
196
|
-
needs: build
|
|
197
|
-
steps:
|
|
198
|
-
- id: deployment
|
|
199
|
-
uses: actions/deploy-pages@v4
|
|
200
|
-
`;
|
|
201
268
|
|
|
202
269
|
export {
|
|
203
270
|
runDeploy
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
htmlShell,
|
|
14
14
|
initSentry,
|
|
15
15
|
loadPlugins
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-WSJC3PRH.js";
|
|
17
17
|
import {
|
|
18
18
|
cspHeader,
|
|
19
19
|
generateNonce,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "./chunk-EOK6KATZ.js";
|
|
22
22
|
import {
|
|
23
23
|
logger
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-TU7G4RJV.js";
|
|
25
25
|
import {
|
|
26
26
|
ASSETS_DIR,
|
|
27
27
|
CACHE_FILE,
|
|
@@ -103,8 +103,8 @@ var BuildPluginBuilder = class {
|
|
|
103
103
|
_remarkPlugins = [];
|
|
104
104
|
_transformFrontmatter = [];
|
|
105
105
|
_transformHtml = [];
|
|
106
|
-
constructor(
|
|
107
|
-
this.config =
|
|
106
|
+
constructor(config2) {
|
|
107
|
+
this.config = config2;
|
|
108
108
|
}
|
|
109
109
|
/**
|
|
110
110
|
* Collect and deduplicate all `<body>` injection snippets from registered plugins.
|
|
@@ -646,8 +646,8 @@ function getThemeConfig() {
|
|
|
646
646
|
if (process.env.FLAME_THEME) {
|
|
647
647
|
return process.env.FLAME_THEME;
|
|
648
648
|
}
|
|
649
|
-
const
|
|
650
|
-
return
|
|
649
|
+
const config2 = loadDocuConfig();
|
|
650
|
+
return config2.themes?.colors;
|
|
651
651
|
}
|
|
652
652
|
function buildThemeCss(baseCss, themeConfig) {
|
|
653
653
|
try {
|
|
@@ -683,19 +683,19 @@ import { existsSync, readFileSync, readdirSync as readdirSync2 } from "node:fs";
|
|
|
683
683
|
import { promisify } from "node:util";
|
|
684
684
|
import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
685
685
|
import { createHash } from "node:crypto";
|
|
686
|
-
function extractConfigIcons(
|
|
686
|
+
function extractConfigIcons(config2) {
|
|
687
687
|
const icons = [];
|
|
688
688
|
const pushIf = (s) => {
|
|
689
689
|
if (s) icons.push(s);
|
|
690
690
|
};
|
|
691
|
-
|
|
692
|
-
|
|
691
|
+
config2.home?.hero?.actions?.forEach((a) => pushIf(a.icon));
|
|
692
|
+
config2.home?.features?.forEach((f) => pushIf(f.icon));
|
|
693
693
|
(function walk(routes3) {
|
|
694
694
|
for (const r of routes3) {
|
|
695
695
|
pushIf(r.context?.icon);
|
|
696
696
|
if (r.items) walk(r.items);
|
|
697
697
|
}
|
|
698
|
-
})(
|
|
698
|
+
})(config2.routes ?? []);
|
|
699
699
|
return [...new Set(icons.filter((n) => /^[A-Z]/.test(n)))];
|
|
700
700
|
}
|
|
701
701
|
var execFileAsync = promisify(execFile);
|
|
@@ -874,17 +874,25 @@ async function buildClientBundle() {
|
|
|
874
874
|
{
|
|
875
875
|
name: "docu-config",
|
|
876
876
|
setup(build2) {
|
|
877
|
-
build2.onResolve({ filter: /
|
|
877
|
+
build2.onResolve({ filter: /client-routes$/ }, (args) => ({
|
|
878
878
|
path: args.path,
|
|
879
|
-
namespace: "
|
|
879
|
+
namespace: "client-routes"
|
|
880
880
|
}));
|
|
881
|
-
build2.onLoad({ filter: /.*/, namespace: "
|
|
882
|
-
const
|
|
881
|
+
build2.onLoad({ filter: /.*/, namespace: "client-routes" }, () => {
|
|
882
|
+
const config2 = loadDocuConfig();
|
|
883
883
|
const resolved = {
|
|
884
|
-
...
|
|
885
|
-
routes: resolveRoutes(
|
|
884
|
+
...config2,
|
|
885
|
+
routes: resolveRoutes(config2.routes)
|
|
886
|
+
};
|
|
887
|
+
return {
|
|
888
|
+
contents: [
|
|
889
|
+
`import type { DocuRoute, DocuConfig } from "./types";`,
|
|
890
|
+
`const docuConfig = ${JSON.stringify(resolved)};`,
|
|
891
|
+
`export const routes = docuConfig.routes || [];`,
|
|
892
|
+
`export const config = docuConfig;`
|
|
893
|
+
].join("\n"),
|
|
894
|
+
loader: "ts"
|
|
886
895
|
};
|
|
887
|
-
return { contents: JSON.stringify(resolved), loader: "json" };
|
|
888
896
|
});
|
|
889
897
|
}
|
|
890
898
|
}
|
|
@@ -2028,15 +2036,10 @@ function Anchor({
|
|
|
2028
2036
|
return /* @__PURE__ */ jsx15("a", { href, className: baseClasses, ...props, children });
|
|
2029
2037
|
}
|
|
2030
2038
|
|
|
2031
|
-
// docu-config-runtime:../../docu.json
|
|
2032
|
-
import { readFileSync as readFileSync2 } from "node:fs";
|
|
2033
|
-
import { join as join4 } from "node:path";
|
|
2034
|
-
var config = JSON.parse(readFileSync2(join4(process.cwd(), "docu.json"), "utf-8"));
|
|
2035
|
-
var docu_default = config;
|
|
2036
|
-
|
|
2037
2039
|
// .docu/node/client-routes.ts
|
|
2038
|
-
var
|
|
2039
|
-
var
|
|
2040
|
+
var docuConfig5 = loadDocuConfig();
|
|
2041
|
+
var routes2 = resolveRoutes(docuConfig5.routes || []);
|
|
2042
|
+
var config = docuConfig5;
|
|
2040
2043
|
|
|
2041
2044
|
// .docu/components/Sublink.tsx
|
|
2042
2045
|
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
@@ -2078,7 +2081,7 @@ function Sublink({
|
|
|
2078
2081
|
}
|
|
2079
2082
|
);
|
|
2080
2083
|
if (level >= 1) {
|
|
2081
|
-
if (
|
|
2084
|
+
if (config.sidebar?.context === "separator") {
|
|
2082
2085
|
const sectionOffsets = { 1: 16, 2: 32 };
|
|
2083
2086
|
let overlap = 14;
|
|
2084
2087
|
for (let l = 1; l < level; l++) {
|
|
@@ -2187,7 +2190,7 @@ function Menu({ onNavigate, className = "", pathname, routes: routes3 = [] }) {
|
|
|
2187
2190
|
() => pathname || (typeof window !== "undefined" ? window.location.pathname : "/docs")
|
|
2188
2191
|
);
|
|
2189
2192
|
if (!currentPath.startsWith("/docs")) return null;
|
|
2190
|
-
const mode =
|
|
2193
|
+
const mode = config.sidebar?.context || "dropdown";
|
|
2191
2194
|
const navProps = {
|
|
2192
2195
|
"aria-label": "Documentation navigation",
|
|
2193
2196
|
className: cn("transition-all duration-200", className)
|
|
@@ -2249,7 +2252,7 @@ function Menu({ onNavigate, className = "", pathname, routes: routes3 = [] }) {
|
|
|
2249
2252
|
}
|
|
2250
2253
|
|
|
2251
2254
|
// .docu/components/DocsLayout.tsx
|
|
2252
|
-
var
|
|
2255
|
+
var docuConfig6 = loadDocuConfig();
|
|
2253
2256
|
function DocsLayout({ children, repoUrl, pathname = "/docs" }) {
|
|
2254
2257
|
return React2.createElement(
|
|
2255
2258
|
"div",
|
|
@@ -2270,7 +2273,7 @@ function DocsLayout({ children, repoUrl, pathname = "/docs" }) {
|
|
|
2270
2273
|
React2.createElement(
|
|
2271
2274
|
"div",
|
|
2272
2275
|
{ className: "flex h-full flex-col overflow-y-auto px-4" },
|
|
2273
|
-
React2.createElement(Menu, { pathname, routes:
|
|
2276
|
+
React2.createElement(Menu, { pathname, routes: docuConfig6.routes || [] })
|
|
2274
2277
|
)
|
|
2275
2278
|
),
|
|
2276
2279
|
React2.createElement(
|
|
@@ -2282,7 +2285,7 @@ function DocsLayout({ children, repoUrl, pathname = "/docs" }) {
|
|
|
2282
2285
|
React2.createElement(
|
|
2283
2286
|
"nav",
|
|
2284
2287
|
{ className: "flex items-center gap-6 text-sm font-medium text-base-content/80" },
|
|
2285
|
-
...(
|
|
2288
|
+
...(docuConfig6.navbar?.menu || []).map((item) => {
|
|
2286
2289
|
const isExternal = /^https?:\/\//.test(item.href);
|
|
2287
2290
|
const isDocsActive = item.href === "/docs";
|
|
2288
2291
|
return React2.createElement(
|
package/.docu/lib/clean.js
CHANGED
package/.docu/lib/deploy.deno.js
CHANGED
package/.docu/lib/deploy.node.js
CHANGED
package/.docu/lib/server.deno.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runServer
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-77NNQDFX.js";
|
|
4
|
+
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-TU7G4RJV.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/server.deno.ts
|
package/.docu/lib/server.node.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runServer
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-77NNQDFX.js";
|
|
4
|
+
import "./chunk-WSJC3PRH.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-TU7G4RJV.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/server.node.ts
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { DocuRoute, DocuConfig } from "./types";
|
|
2
|
-
import
|
|
2
|
+
import { loadDocuConfig } from "./paths";
|
|
3
|
+
import { resolveRoutes } from "./fs-scanner";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const docuConfig = loadDocuConfig();
|
|
6
|
+
export const routes: DocuRoute[] = resolveRoutes(docuConfig.routes || []);
|
|
5
7
|
export const config = docuConfig as unknown as DocuConfig;
|
|
@@ -16,6 +16,113 @@ import { DIST_DIR, PROJECT_ROOT } from "./paths";
|
|
|
16
16
|
const WORKFLOW_DIR = join(PROJECT_ROOT, ".github/workflows");
|
|
17
17
|
const WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy.yml");
|
|
18
18
|
|
|
19
|
+
export const NGINX_CONF = `server {
|
|
20
|
+
listen 80;
|
|
21
|
+
server_name _;
|
|
22
|
+
root /usr/share/nginx/html;
|
|
23
|
+
index index.html;
|
|
24
|
+
|
|
25
|
+
gzip on;
|
|
26
|
+
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
27
|
+
|
|
28
|
+
# Security headers (HSTS effective when HTTPS is terminated upstream)
|
|
29
|
+
add_header X-Frame-Options "DENY" always;
|
|
30
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
31
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
32
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
33
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
34
|
+
|
|
35
|
+
location /assets/ {
|
|
36
|
+
expires 1y;
|
|
37
|
+
add_header Cache-Control "public, immutable";
|
|
38
|
+
add_header X-Frame-Options "DENY" always;
|
|
39
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
40
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
41
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
42
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
location /docs/assets/ {
|
|
46
|
+
expires 7d;
|
|
47
|
+
add_header Cache-Control "public";
|
|
48
|
+
add_header X-Frame-Options "DENY" always;
|
|
49
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
50
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
51
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
52
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
location / {
|
|
56
|
+
try_files $uri $uri.html $uri/ =404;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
|
|
61
|
+
export const DOCKERIGNORE = `node_modules
|
|
62
|
+
.git
|
|
63
|
+
*.DS_Store
|
|
64
|
+
.docu/dist
|
|
65
|
+
.docu/lib
|
|
66
|
+
.env
|
|
67
|
+
.env.*
|
|
68
|
+
.npmrc
|
|
69
|
+
*.log
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
export function detectPkgManager(dir: string): {
|
|
73
|
+
baseImage: string;
|
|
74
|
+
lockFile: string;
|
|
75
|
+
installCmd: string;
|
|
76
|
+
runCmd: string;
|
|
77
|
+
cache: string;
|
|
78
|
+
setupAction: string;
|
|
79
|
+
} {
|
|
80
|
+
const bunLockFile = existsSync(join(dir, "bun.lock"))
|
|
81
|
+
? "bun.lock"
|
|
82
|
+
: existsSync(join(dir, "bun.lockb"))
|
|
83
|
+
? "bun.lockb"
|
|
84
|
+
: null;
|
|
85
|
+
if (bunLockFile) {
|
|
86
|
+
return {
|
|
87
|
+
baseImage: "oven/bun:1",
|
|
88
|
+
lockFile: bunLockFile,
|
|
89
|
+
installCmd: "bun install --frozen-lockfile",
|
|
90
|
+
runCmd: "bun",
|
|
91
|
+
cache: "",
|
|
92
|
+
setupAction: "bun",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (existsSync(join(dir, "pnpm-lock.yaml"))) {
|
|
96
|
+
return {
|
|
97
|
+
baseImage: "node:22-alpine",
|
|
98
|
+
lockFile: "pnpm-lock.yaml",
|
|
99
|
+
installCmd: "corepack enable && pnpm install --frozen-lockfile",
|
|
100
|
+
runCmd: "pnpm",
|
|
101
|
+
cache: "pnpm",
|
|
102
|
+
setupAction: "pnpm",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (existsSync(join(dir, "yarn.lock"))) {
|
|
106
|
+
return {
|
|
107
|
+
baseImage: "node:22-alpine",
|
|
108
|
+
lockFile: "yarn.lock",
|
|
109
|
+
installCmd: "yarn install --frozen-lockfile",
|
|
110
|
+
runCmd: "yarn",
|
|
111
|
+
cache: "yarn",
|
|
112
|
+
setupAction: "node",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// default: npm
|
|
116
|
+
return {
|
|
117
|
+
baseImage: "node:22-alpine",
|
|
118
|
+
lockFile: "package-lock.json",
|
|
119
|
+
installCmd: "npm ci",
|
|
120
|
+
runCmd: "npm",
|
|
121
|
+
cache: "npm",
|
|
122
|
+
setupAction: "node",
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
19
126
|
export const HEADERS_FILE = `/*
|
|
20
127
|
X-Frame-Options: DENY
|
|
21
128
|
X-Content-Type-Options: nosniff
|
|
@@ -50,16 +157,17 @@ async function runBuild() {
|
|
|
50
157
|
|
|
51
158
|
async function writeDockerFiles() {
|
|
52
159
|
const dockerDir = PROJECT_ROOT;
|
|
160
|
+
const pm = detectPkgManager(dockerDir);
|
|
53
161
|
|
|
54
162
|
if (!existsSync(join(dockerDir, "Dockerfile"))) {
|
|
55
163
|
await writeFile(
|
|
56
164
|
join(dockerDir, "Dockerfile"),
|
|
57
|
-
`FROM
|
|
165
|
+
`FROM ${pm.baseImage} AS builder
|
|
58
166
|
WORKDIR /app
|
|
59
|
-
COPY package.json
|
|
60
|
-
RUN
|
|
167
|
+
COPY package.json ${pm.lockFile} ./
|
|
168
|
+
RUN ${pm.installCmd}
|
|
61
169
|
COPY . .
|
|
62
|
-
RUN
|
|
170
|
+
RUN ${pm.runCmd} run build
|
|
63
171
|
|
|
64
172
|
FROM nginx:alpine
|
|
65
173
|
COPY --from=builder /app/.docu/dist /usr/share/nginx/html
|
|
@@ -73,75 +181,103 @@ CMD ["nginx", "-g", "daemon off;"]
|
|
|
73
181
|
}
|
|
74
182
|
|
|
75
183
|
if (!existsSync(join(dockerDir, "nginx.conf"))) {
|
|
76
|
-
await writeFile(
|
|
77
|
-
|
|
78
|
-
`server {
|
|
79
|
-
listen 80;
|
|
80
|
-
server_name _;
|
|
81
|
-
root /usr/share/nginx/html;
|
|
82
|
-
index index.html;
|
|
83
|
-
|
|
84
|
-
gzip on;
|
|
85
|
-
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
86
|
-
|
|
87
|
-
# Security headers (HSTS effective when HTTPS is terminated upstream)
|
|
88
|
-
add_header X-Frame-Options "DENY" always;
|
|
89
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
90
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
91
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
92
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
93
|
-
|
|
94
|
-
location /assets/ {
|
|
95
|
-
expires 1y;
|
|
96
|
-
add_header Cache-Control "public, immutable";
|
|
97
|
-
add_header X-Frame-Options "DENY" always;
|
|
98
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
99
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
100
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
101
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
location /docs/assets/ {
|
|
105
|
-
expires 7d;
|
|
106
|
-
add_header Cache-Control "public";
|
|
107
|
-
add_header X-Frame-Options "DENY" always;
|
|
108
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
109
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
110
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
111
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
184
|
+
await writeFile(join(dockerDir, "nginx.conf"), NGINX_CONF);
|
|
185
|
+
log.created("📄 Created nginx.conf");
|
|
112
186
|
}
|
|
113
187
|
|
|
114
|
-
|
|
115
|
-
|
|
188
|
+
if (!existsSync(join(dockerDir, ".dockerignore"))) {
|
|
189
|
+
await writeFile(join(dockerDir, ".dockerignore"), DOCKERIGNORE);
|
|
190
|
+
log.created("📄 Created .dockerignore");
|
|
116
191
|
}
|
|
117
192
|
}
|
|
118
|
-
`
|
|
119
|
-
);
|
|
120
|
-
log.created("📄 Created nginx.conf");
|
|
121
|
-
}
|
|
122
193
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
.
|
|
134
|
-
|
|
135
|
-
|
|
194
|
+
function generateWorkflowYml(): string {
|
|
195
|
+
const pm = detectPkgManager(PROJECT_ROOT);
|
|
196
|
+
|
|
197
|
+
const setupSteps: string[] = [
|
|
198
|
+
" - uses: actions/checkout@v7",
|
|
199
|
+
" with:",
|
|
200
|
+
" fetch-depth: 0",
|
|
201
|
+
"",
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
if (pm.setupAction === "bun") {
|
|
205
|
+
setupSteps.push(
|
|
206
|
+
" - uses: oven-sh/setup-bun@v2",
|
|
207
|
+
" with:",
|
|
208
|
+
" bun-version: latest",
|
|
209
|
+
""
|
|
210
|
+
);
|
|
211
|
+
} else if (pm.setupAction === "pnpm") {
|
|
212
|
+
setupSteps.push(
|
|
213
|
+
" - uses: pnpm/action-setup@v6",
|
|
214
|
+
"",
|
|
215
|
+
" - uses: actions/setup-node@v6",
|
|
216
|
+
" with:",
|
|
217
|
+
" node-version: 22",
|
|
218
|
+
` cache: ${pm.cache}`,
|
|
219
|
+
""
|
|
220
|
+
);
|
|
221
|
+
} else {
|
|
222
|
+
// npm / yarn
|
|
223
|
+
setupSteps.push(
|
|
224
|
+
" - uses: actions/setup-node@v6",
|
|
225
|
+
" with:",
|
|
226
|
+
" node-version: 22",
|
|
227
|
+
` cache: ${pm.cache}`,
|
|
228
|
+
""
|
|
136
229
|
);
|
|
137
|
-
log.created("📄 Created .dockerignore");
|
|
138
230
|
}
|
|
231
|
+
|
|
232
|
+
return [
|
|
233
|
+
`name: Deploy to GitHub Pages`,
|
|
234
|
+
"",
|
|
235
|
+
"on:",
|
|
236
|
+
" push:",
|
|
237
|
+
" branches: [main]",
|
|
238
|
+
" workflow_dispatch:",
|
|
239
|
+
"",
|
|
240
|
+
"permissions:",
|
|
241
|
+
" contents: read",
|
|
242
|
+
" pages: write",
|
|
243
|
+
" id-token: write",
|
|
244
|
+
"",
|
|
245
|
+
"concurrency:",
|
|
246
|
+
' group: "pages"',
|
|
247
|
+
" cancel-in-progress: false",
|
|
248
|
+
"",
|
|
249
|
+
"jobs:",
|
|
250
|
+
" build:",
|
|
251
|
+
" runs-on: ubuntu-latest",
|
|
252
|
+
" steps:",
|
|
253
|
+
...setupSteps,
|
|
254
|
+
` - run: ${pm.installCmd}`,
|
|
255
|
+
"",
|
|
256
|
+
` - run: ${pm.runCmd} run build`,
|
|
257
|
+
"",
|
|
258
|
+
" - name: Add .nojekyll",
|
|
259
|
+
" run: touch .docu/dist/.nojekyll",
|
|
260
|
+
"",
|
|
261
|
+
" - uses: actions/upload-pages-artifact@v3",
|
|
262
|
+
" with:",
|
|
263
|
+
" path: .docu/dist",
|
|
264
|
+
"",
|
|
265
|
+
" deploy:",
|
|
266
|
+
" environment:",
|
|
267
|
+
" name: github-pages",
|
|
268
|
+
" url: ${{ steps.deployment.outputs.page_url }}",
|
|
269
|
+
" runs-on: ubuntu-latest",
|
|
270
|
+
" needs: build",
|
|
271
|
+
" steps:",
|
|
272
|
+
" - id: deployment",
|
|
273
|
+
" uses: actions/deploy-pages@v4",
|
|
274
|
+
].join("\n");
|
|
139
275
|
}
|
|
140
276
|
|
|
141
277
|
async function writeGhaWorkflow() {
|
|
142
278
|
if (!existsSync(WORKFLOW_FILE)) {
|
|
143
279
|
await mkdir(WORKFLOW_DIR, { recursive: true });
|
|
144
|
-
await writeFile(WORKFLOW_FILE,
|
|
280
|
+
await writeFile(WORKFLOW_FILE, generateWorkflowYml());
|
|
145
281
|
log.created("📄 Created .github/workflows/deploy.yml");
|
|
146
282
|
}
|
|
147
283
|
}
|
|
@@ -168,53 +304,3 @@ export async function runDeploy(): Promise<void> {
|
|
|
168
304
|
log.out(" Push to GitHub and enable Pages (Settings → Pages → Source: GitHub Actions)");
|
|
169
305
|
}
|
|
170
306
|
}
|
|
171
|
-
|
|
172
|
-
const GITHUB_ACTIONS_WORKFLOW = `name: Deploy to GitHub Pages
|
|
173
|
-
|
|
174
|
-
on:
|
|
175
|
-
push:
|
|
176
|
-
branches: [main]
|
|
177
|
-
workflow_dispatch:
|
|
178
|
-
|
|
179
|
-
permissions:
|
|
180
|
-
contents: read
|
|
181
|
-
pages: write
|
|
182
|
-
id-token: write
|
|
183
|
-
|
|
184
|
-
concurrency:
|
|
185
|
-
group: "pages"
|
|
186
|
-
cancel-in-progress: false
|
|
187
|
-
|
|
188
|
-
jobs:
|
|
189
|
-
build:
|
|
190
|
-
runs-on: ubuntu-latest
|
|
191
|
-
steps:
|
|
192
|
-
- uses: actions/checkout@v4
|
|
193
|
-
with:
|
|
194
|
-
fetch-depth: 0
|
|
195
|
-
|
|
196
|
-
- uses: actions/setup-node@v4
|
|
197
|
-
with:
|
|
198
|
-
node-version: 22
|
|
199
|
-
|
|
200
|
-
- run: npm install
|
|
201
|
-
|
|
202
|
-
- run: npm run build
|
|
203
|
-
|
|
204
|
-
- name: Add .nojekyll
|
|
205
|
-
run: touch .docu/dist/.nojekyll
|
|
206
|
-
|
|
207
|
-
- uses: actions/upload-pages-artifact@v3
|
|
208
|
-
with:
|
|
209
|
-
path: .docu/dist
|
|
210
|
-
|
|
211
|
-
deploy:
|
|
212
|
-
environment:
|
|
213
|
-
name: github-pages
|
|
214
|
-
url: \${{ steps.deployment.outputs.page_url }}
|
|
215
|
-
runs-on: ubuntu-latest
|
|
216
|
-
needs: build
|
|
217
|
-
steps:
|
|
218
|
-
- id: deployment
|
|
219
|
-
uses: actions/deploy-pages@v4
|
|
220
|
-
`;
|
package/.docu/node/deploy.ts
CHANGED
|
@@ -11,9 +11,9 @@ import { mkdir } from "node:fs/promises";
|
|
|
11
11
|
import { existsSync } from "node:fs";
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { DIST_DIR, PROJECT_ROOT } from "./paths";
|
|
14
|
-
import { HEADERS_FILE } from "./deploy.shared";
|
|
14
|
+
import { HEADERS_FILE, NGINX_CONF, DOCKERIGNORE } from "./deploy.shared";
|
|
15
15
|
|
|
16
|
-
export { HEADERS_FILE };
|
|
16
|
+
export { HEADERS_FILE, NGINX_CONF, DOCKERIGNORE };
|
|
17
17
|
|
|
18
18
|
const WORKFLOW_DIR = join(PROJECT_ROOT, ".github/workflows");
|
|
19
19
|
const WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy.yml");
|
|
@@ -43,49 +43,6 @@ async function runBuild() {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
export const NGINX_CONF = `server {
|
|
47
|
-
listen 80;
|
|
48
|
-
server_name _;
|
|
49
|
-
root /usr/share/nginx/html;
|
|
50
|
-
index index.html;
|
|
51
|
-
|
|
52
|
-
gzip on;
|
|
53
|
-
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
54
|
-
|
|
55
|
-
# Security headers (server-level, inherited by all locations)
|
|
56
|
-
# HSTS effective when HTTPS is terminated upstream (reverse proxy / LB)
|
|
57
|
-
add_header X-Frame-Options "DENY" always;
|
|
58
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
59
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
60
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
61
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
62
|
-
|
|
63
|
-
location /assets/ {
|
|
64
|
-
expires 1y;
|
|
65
|
-
add_header Cache-Control "public, immutable";
|
|
66
|
-
add_header X-Frame-Options "DENY" always;
|
|
67
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
68
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
69
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
70
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
location /docs/assets/ {
|
|
74
|
-
expires 7d;
|
|
75
|
-
add_header Cache-Control "public";
|
|
76
|
-
add_header X-Frame-Options "DENY" always;
|
|
77
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
78
|
-
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
79
|
-
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
80
|
-
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
location / {
|
|
84
|
-
try_files $uri $uri.html $uri/ =404;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
`;
|
|
88
|
-
|
|
89
46
|
export const DOCKERFILE_BUN = `FROM oven/bun:1 AS builder
|
|
90
47
|
WORKDIR /app
|
|
91
48
|
COPY package.json bun.lock ./
|
|
@@ -101,17 +58,6 @@ EXPOSE 80
|
|
|
101
58
|
CMD ["nginx", "-g", "daemon off;"]
|
|
102
59
|
`;
|
|
103
60
|
|
|
104
|
-
export const DOCKERIGNORE = `node_modules
|
|
105
|
-
.git
|
|
106
|
-
*.DS_Store
|
|
107
|
-
.docu/dist
|
|
108
|
-
.docu/lib
|
|
109
|
-
.env
|
|
110
|
-
.env.*
|
|
111
|
-
.npmrc
|
|
112
|
-
*.log
|
|
113
|
-
`;
|
|
114
|
-
|
|
115
61
|
async function writeDockerFiles() {
|
|
116
62
|
const dockerDir = PROJECT_ROOT;
|
|
117
63
|
|
|
@@ -182,7 +128,7 @@ jobs:
|
|
|
182
128
|
build:
|
|
183
129
|
runs-on: ubuntu-latest
|
|
184
130
|
steps:
|
|
185
|
-
- uses: actions/checkout@
|
|
131
|
+
- uses: actions/checkout@v7
|
|
186
132
|
with:
|
|
187
133
|
fetch-depth: 0
|
|
188
134
|
|
|
@@ -270,17 +270,27 @@ export async function buildClientBundle(): Promise<{ js: string; css: string }>
|
|
|
270
270
|
{
|
|
271
271
|
name: "docu-config",
|
|
272
272
|
setup(build) {
|
|
273
|
-
|
|
273
|
+
// Components import as "../node/client-routes" (no .ts extension),
|
|
274
|
+
// so filter matches the path tail without requiring the extension.
|
|
275
|
+
build.onResolve({ filter: /client-routes$/ }, (args) => ({
|
|
274
276
|
path: args.path,
|
|
275
|
-
namespace: "
|
|
277
|
+
namespace: "client-routes",
|
|
276
278
|
}));
|
|
277
|
-
build.onLoad({ filter: /.*/, namespace: "
|
|
279
|
+
build.onLoad({ filter: /.*/, namespace: "client-routes" }, () => {
|
|
278
280
|
const config = loadDocuConfig();
|
|
279
281
|
const resolved = {
|
|
280
282
|
...config,
|
|
281
283
|
routes: resolveRoutes(config.routes as DocuRoute[] | undefined),
|
|
282
284
|
};
|
|
283
|
-
return {
|
|
285
|
+
return {
|
|
286
|
+
contents: [
|
|
287
|
+
`import type { DocuRoute, DocuConfig } from "./types";`,
|
|
288
|
+
`const docuConfig = ${JSON.stringify(resolved)};`,
|
|
289
|
+
`export const routes = docuConfig.routes || [];`,
|
|
290
|
+
`export const config = docuConfig;`,
|
|
291
|
+
].join("\n"),
|
|
292
|
+
loader: "ts",
|
|
293
|
+
};
|
|
284
294
|
});
|
|
285
295
|
},
|
|
286
296
|
},
|
package/.docu/node/hydrate.ts
CHANGED
|
@@ -142,17 +142,27 @@ export async function buildClientBundle(): Promise<{ js: string; css: string }>
|
|
|
142
142
|
{
|
|
143
143
|
name: "docu-config",
|
|
144
144
|
setup(build) {
|
|
145
|
-
|
|
145
|
+
// Components import as "../node/client-routes" (no .ts extension),
|
|
146
|
+
// so filter matches the path tail without requiring the extension.
|
|
147
|
+
build.onResolve({ filter: /client-routes$/ }, (args) => ({
|
|
146
148
|
path: args.path,
|
|
147
|
-
namespace: "
|
|
149
|
+
namespace: "client-routes",
|
|
148
150
|
}));
|
|
149
|
-
build.onLoad({ filter: /.*/, namespace: "
|
|
151
|
+
build.onLoad({ filter: /.*/, namespace: "client-routes" }, () => {
|
|
150
152
|
const config = loadDocuConfig();
|
|
151
153
|
const resolved = {
|
|
152
154
|
...config,
|
|
153
155
|
routes: resolveRoutes(config.routes as DocuRoute[] | undefined),
|
|
154
156
|
};
|
|
155
|
-
return {
|
|
157
|
+
return {
|
|
158
|
+
contents: [
|
|
159
|
+
`import type { DocuRoute, DocuConfig } from "./types";`,
|
|
160
|
+
`const docuConfig = ${JSON.stringify(resolved)};`,
|
|
161
|
+
`export const routes = docuConfig.routes || [];`,
|
|
162
|
+
`export const config = docuConfig;`,
|
|
163
|
+
].join("\n"),
|
|
164
|
+
loader: "ts",
|
|
165
|
+
};
|
|
156
166
|
});
|
|
157
167
|
},
|
|
158
168
|
},
|
package/bin/compile-lib.mjs
CHANGED
|
@@ -35,30 +35,6 @@ await build({
|
|
|
35
35
|
packages: "external",
|
|
36
36
|
jsx: "automatic",
|
|
37
37
|
logLevel: "info",
|
|
38
|
-
plugins: [
|
|
39
|
-
{
|
|
40
|
-
// The SSR component graph imports `docu.json` statically
|
|
41
|
-
// (client-routes.ts). At runtime that must be the USER's project
|
|
42
|
-
// config, so replace the import with a cwd-relative read instead of
|
|
43
|
-
// baking the monorepo's docu.json into the published bundle.
|
|
44
|
-
name: "docu-config-runtime",
|
|
45
|
-
setup(build) {
|
|
46
|
-
build.onResolve({ filter: /docu\.json$/ }, (args) => ({
|
|
47
|
-
path: args.path,
|
|
48
|
-
namespace: "docu-config-runtime",
|
|
49
|
-
}));
|
|
50
|
-
build.onLoad({ filter: /.*/, namespace: "docu-config-runtime" }, () => ({
|
|
51
|
-
contents: [
|
|
52
|
-
`import { readFileSync } from "node:fs";`,
|
|
53
|
-
`import { join } from "node:path";`,
|
|
54
|
-
`const config = JSON.parse(readFileSync(join(process.cwd(), "docu.json"), "utf-8"));`,
|
|
55
|
-
`export default config;`,
|
|
56
|
-
].join("\n"),
|
|
57
|
-
loader: "js",
|
|
58
|
-
}));
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
38
|
});
|
|
63
39
|
|
|
64
40
|
// esbuild's service process keeps Deno's event loop alive after one-shot
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docubook/flame",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"@docubook/core": "^1.8.2",
|
|
58
58
|
"@docubook/mdx-content": "^3.4.5",
|
|
59
59
|
"@docubook/runt": "^1.0.0",
|
|
60
|
-
"@docubook/
|
|
61
|
-
"@docubook/
|
|
60
|
+
"@docubook/ui-react": "^1.0.0",
|
|
61
|
+
"@docubook/themes-colors": "^1.0.2"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"@sentry/bun": "^10.0.0"
|