@docubook/flame 1.6.0 → 1.6.1
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 +2 -2
- package/.docu/lib/{build.impl-N2MBT3CM.js → build.impl-5VMX2INF.js} +2 -2
- package/.docu/lib/build.node.js +2 -2
- package/.docu/lib/{chunk-Y2TAEAUQ.js → chunk-2VUUBIN3.js} +1 -1
- package/.docu/lib/{chunk-TI6M4643.js → chunk-EINCC7ET.js} +178 -111
- package/.docu/lib/{chunk-ZA5QB5UK.js → chunk-GC62TPBC.js} +1 -1
- package/.docu/lib/{chunk-UUS45SUC.js → chunk-P3ZT4S3D.js} +1 -1
- package/.docu/lib/{chunk-JTH4JBBS.js → chunk-XX2VVJMV.js} +1 -1
- 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 +2 -2
- package/.docu/lib/server.node.js +2 -2
- package/.docu/node/deploy.shared.ts +197 -111
- package/.docu/node/deploy.ts +3 -57
- 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-
|
|
3
|
+
} from "./chunk-XX2VVJMV.js";
|
|
4
4
|
import "./chunk-IJFMQFWW.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-2VUUBIN3.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-
|
|
4
|
+
} from "./chunk-XX2VVJMV.js";
|
|
5
5
|
import "./chunk-IJFMQFWW.js";
|
|
6
6
|
import "./chunk-EOK6KATZ.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-2VUUBIN3.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-
|
|
3
|
+
} from "./chunk-XX2VVJMV.js";
|
|
4
4
|
import "./chunk-IJFMQFWW.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-2VUUBIN3.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/build.node.ts
|
|
@@ -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-5VMX2INF.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
|
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-
|
|
3
|
+
} from "./chunk-GC62TPBC.js";
|
|
4
4
|
import "./chunk-IJFMQFWW.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-2VUUBIN3.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-
|
|
3
|
+
} from "./chunk-GC62TPBC.js";
|
|
4
4
|
import "./chunk-IJFMQFWW.js";
|
|
5
5
|
import "./chunk-EOK6KATZ.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-2VUUBIN3.js";
|
|
7
7
|
import "./chunk-4IQXHHPF.js";
|
|
8
8
|
|
|
9
9
|
// .docu/node/server.node.ts
|
|
@@ -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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docubook/flame",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"unified": "^11.0.0",
|
|
57
57
|
"@docubook/core": "^1.8.2",
|
|
58
58
|
"@docubook/mdx-content": "^3.4.5",
|
|
59
|
-
"@docubook/runt": "^1.0.0",
|
|
60
59
|
"@docubook/themes-colors": "^1.0.2",
|
|
61
|
-
"@docubook/ui-react": "^1.0.0"
|
|
60
|
+
"@docubook/ui-react": "^1.0.0",
|
|
61
|
+
"@docubook/runt": "^1.0.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"@sentry/bun": "^10.0.0"
|