@docubook/flame 2.0.0-beta.1 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docu/lib/build.deno.js +6 -9
- package/.docu/lib/build.deno.js.map +1 -0
- package/.docu/lib/build.impl-Bz_p421t.js +424 -0
- package/.docu/lib/build.impl-Bz_p421t.js.map +1 -0
- package/.docu/lib/build.impl-CtPrlYAE.js +2 -0
- package/.docu/lib/build.node.js +6 -9
- package/.docu/lib/build.node.js.map +1 -0
- package/.docu/lib/clean.js +25 -25
- package/.docu/lib/clean.js.map +1 -0
- package/.docu/lib/deno-DmEaKggj.js +20 -0
- package/.docu/lib/deno-DmEaKggj.js.map +1 -0
- package/.docu/lib/deploy.deno.js +9 -9
- package/.docu/lib/deploy.deno.js.map +1 -0
- package/.docu/lib/deploy.node.js +8 -8
- package/.docu/lib/deploy.node.js.map +1 -0
- package/.docu/lib/deploy.shared-fk8eM-r4.js +295 -0
- package/.docu/lib/deploy.shared-fk8eM-r4.js.map +1 -0
- package/.docu/lib/html.shared-FwgbE1WG.js +2696 -0
- package/.docu/lib/html.shared-FwgbE1WG.js.map +1 -0
- package/.docu/lib/logger-CQyNTE6L.js +306 -0
- package/.docu/lib/logger-CQyNTE6L.js.map +1 -0
- package/.docu/lib/node-DPTySdwG.js +80 -0
- package/.docu/lib/node-DPTySdwG.js.map +1 -0
- package/.docu/lib/paths-Bl2cdp9E.js +76 -0
- package/.docu/lib/paths-Bl2cdp9E.js.map +1 -0
- package/.docu/lib/preview.deno.js +7 -11
- package/.docu/lib/preview.deno.js.map +1 -0
- package/.docu/lib/preview.impl-CnsbLmDA.js +77 -0
- package/.docu/lib/preview.impl-CnsbLmDA.js.map +1 -0
- package/.docu/lib/preview.node.js +7 -11
- package/.docu/lib/preview.node.js.map +1 -0
- package/.docu/lib/server.deno.js +7 -12
- package/.docu/lib/server.deno.js.map +1 -0
- package/.docu/lib/server.impl-CXTzYqbF.js +358 -0
- package/.docu/lib/server.impl-CXTzYqbF.js.map +1 -0
- package/.docu/lib/server.node.js +7 -12
- package/.docu/lib/server.node.js.map +1 -0
- package/.docu/lib/utils-DA17MyQG.js +167 -0
- package/.docu/lib/utils-DA17MyQG.js.map +1 -0
- package/.docu/node/build.impl.ts +76 -11
- package/.docu/node/build.ts +83 -9
- package/.docu/node/cache-key.ts +311 -0
- package/.docu/node/hydrate.node.ts +124 -177
- package/.docu/node/hydrate.ts +13 -14
- package/.docu/node/mdx.ts +14 -2
- package/.docu/node/paths.ts +27 -1
- package/.docu/node/types.ts +23 -5
- package/bin/cli.js +56 -18
- package/bin/compile-lib.mjs +30 -28
- package/package.json +10 -16
- package/.docu/lib/build.impl-3ZOQORN3.js +0 -12
- package/.docu/lib/chunk-4IQXHHPF.js +0 -62
- package/.docu/lib/chunk-6EOUQCRM.js +0 -301
- package/.docu/lib/chunk-6HFBJUMG.js +0 -434
- package/.docu/lib/chunk-EOK6KATZ.js +0 -191
- package/.docu/lib/chunk-FERG25YW.js +0 -470
- package/.docu/lib/chunk-MQRFIDS4.js +0 -92
- package/.docu/lib/chunk-U7M5SK76.js +0 -330
- package/.docu/lib/chunk-UISOJ4RW.js +0 -114
- package/.docu/lib/chunk-URBATJEC.js +0 -2720
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.deno.js","names":[],"sources":["../node/deploy.deno.ts"],"sourcesContent":["import { runDeploy } from \"./deploy.shared\";\n\ntry {\n await runDeploy();\n} catch (err) {\n console.error(\"Deploy failed:\", err);\n process.exit(1);\n}\n// See build.deno.ts — react-dom/server's browser build keeps Deno's event\n// loop alive after the in-process build; force a clean exit.\nprocess.exit(0);\n"],"mappings":";;AAEA,IAAI;CACF,MAAM,UAAU;AAClB,SAAS,KAAK;CACZ,QAAQ,MAAM,kBAAkB,GAAG;CACnC,QAAQ,KAAK,CAAC;AAChB;AAGA,QAAQ,KAAK,CAAC"}
|
package/.docu/lib/deploy.node.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-U7M5SK76.js";
|
|
4
|
-
import "./chunk-4IQXHHPF.js";
|
|
5
|
-
|
|
6
|
-
// .docu/node/deploy.node.ts
|
|
1
|
+
import { t as runDeploy } from "./deploy.shared-fk8eM-r4.js";
|
|
2
|
+
//#region .docu/node/deploy.node.ts
|
|
7
3
|
runDeploy().catch((err) => {
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
console.error("Deploy failed:", err);
|
|
5
|
+
process.exit(1);
|
|
10
6
|
});
|
|
7
|
+
//#endregion
|
|
8
|
+
export {};
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=deploy.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.node.js","names":[],"sources":["../node/deploy.node.ts"],"sourcesContent":["import { runDeploy } from \"./deploy.shared\";\n\nrunDeploy().catch((err) => {\n console.error(\"Deploy failed:\", err);\n process.exit(1);\n});\n"],"mappings":";;AAEA,UAAU,CAAC,CAAC,OAAO,QAAQ;CACzB,QAAQ,MAAM,kBAAkB,GAAG;CACnC,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { c as PROJECT_ROOT, o as FRAMEWORK_ROOT, r as DIST_DIR } from "./paths-Bl2cdp9E.js";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
+
//#region .docu/node/deploy.shared.ts
|
|
6
|
+
/**
|
|
7
|
+
* Runtime-neutral deploy — 3 modes:
|
|
8
|
+
* 1. `flame deploy` → build + generate GitHub Actions workflow
|
|
9
|
+
* 2. `flame deploy --docker` → build + generate Docker deployment files
|
|
10
|
+
* 3. `flame deploy --docker --silent` → same as #2, minimal output
|
|
11
|
+
*
|
|
12
|
+
* Mirror of deploy.ts (Bun-only, protected) for Node.js and Deno.
|
|
13
|
+
* Runs the neutral build in-process, then prepares .docu/dist.
|
|
14
|
+
*/
|
|
15
|
+
var FLAME_MAJOR = JSON.parse(readFileSync(resolve(FRAMEWORK_ROOT, "package.json"), "utf-8")).version.split(".")[0];
|
|
16
|
+
var WORKFLOW_DIR = join(PROJECT_ROOT, ".github/workflows");
|
|
17
|
+
var WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy.yml");
|
|
18
|
+
var NGINX_CONF = `server {
|
|
19
|
+
listen 80;
|
|
20
|
+
server_name _;
|
|
21
|
+
root /usr/share/nginx/html;
|
|
22
|
+
index index.html;
|
|
23
|
+
|
|
24
|
+
gzip on;
|
|
25
|
+
gzip_types text/html text/css application/javascript image/svg+xml;
|
|
26
|
+
|
|
27
|
+
# Security headers (HSTS effective when HTTPS is terminated upstream)
|
|
28
|
+
add_header X-Frame-Options "DENY" always;
|
|
29
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
30
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
31
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
32
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
33
|
+
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" 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
|
+
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
location /docs/assets/ {
|
|
47
|
+
expires 7d;
|
|
48
|
+
add_header Cache-Control "public";
|
|
49
|
+
add_header X-Frame-Options "DENY" always;
|
|
50
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
51
|
+
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
|
|
52
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
53
|
+
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
|
54
|
+
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'" always;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
location / {
|
|
58
|
+
try_files $uri $uri.html $uri/ =404;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
var DOCKERIGNORE = `node_modules
|
|
63
|
+
*.DS_Store
|
|
64
|
+
.docu/dist
|
|
65
|
+
.docu/lib
|
|
66
|
+
.env
|
|
67
|
+
.env.*
|
|
68
|
+
.npmrc
|
|
69
|
+
*.log
|
|
70
|
+
`;
|
|
71
|
+
function detectPkgManager(dir) {
|
|
72
|
+
const bunLockFile = existsSync(join(dir, "bun.lock")) ? "bun.lock" : existsSync(join(dir, "bun.lockb")) ? "bun.lockb" : null;
|
|
73
|
+
if (bunLockFile) return {
|
|
74
|
+
baseImage: "oven/bun:1-debian",
|
|
75
|
+
lockFile: bunLockFile,
|
|
76
|
+
installCmd: "bun install --frozen-lockfile",
|
|
77
|
+
runCmd: "bun",
|
|
78
|
+
cache: "",
|
|
79
|
+
setupAction: "bun"
|
|
80
|
+
};
|
|
81
|
+
if (existsSync(join(dir, "pnpm-lock.yaml"))) return {
|
|
82
|
+
baseImage: "node:22-alpine",
|
|
83
|
+
lockFile: "pnpm-lock.yaml",
|
|
84
|
+
installCmd: "corepack enable && pnpm install --frozen-lockfile",
|
|
85
|
+
runCmd: "pnpm",
|
|
86
|
+
cache: "pnpm",
|
|
87
|
+
setupAction: "pnpm"
|
|
88
|
+
};
|
|
89
|
+
if (existsSync(join(dir, "yarn.lock"))) return {
|
|
90
|
+
baseImage: "node:22-alpine",
|
|
91
|
+
lockFile: "yarn.lock",
|
|
92
|
+
installCmd: "yarn install --frozen-lockfile",
|
|
93
|
+
runCmd: "yarn",
|
|
94
|
+
cache: "yarn",
|
|
95
|
+
setupAction: "node"
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
baseImage: "node:22-alpine",
|
|
99
|
+
lockFile: "package-lock.json",
|
|
100
|
+
installCmd: "npm ci",
|
|
101
|
+
runCmd: "npm",
|
|
102
|
+
cache: "npm",
|
|
103
|
+
setupAction: "node"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
var HEADERS_FILE = `/*
|
|
107
|
+
X-Frame-Options: DENY
|
|
108
|
+
X-Content-Type-Options: nosniff
|
|
109
|
+
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
|
|
110
|
+
Referrer-Policy: strict-origin-when-cross-origin
|
|
111
|
+
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
|
112
|
+
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'
|
|
113
|
+
|
|
114
|
+
/assets/*
|
|
115
|
+
Cache-Control: public, max-age=31536000, immutable
|
|
116
|
+
`;
|
|
117
|
+
var isDocker = !!process.env.FLAME_DEPLOY_DOCKER;
|
|
118
|
+
var isSilent = !!process.env.FLAME_DEPLOY_SILENT;
|
|
119
|
+
var isCi = !!process.env.FLAME_DEPLOY_CI;
|
|
120
|
+
/** Logger that no-ops all non-error output in silent mode. */
|
|
121
|
+
var log = isSilent ? {
|
|
122
|
+
info: () => {},
|
|
123
|
+
ok: () => {},
|
|
124
|
+
created: () => {},
|
|
125
|
+
out: () => {}
|
|
126
|
+
} : {
|
|
127
|
+
info: (m) => console.log(m),
|
|
128
|
+
ok: () => console.log("\n✅ Ready to deploy!"),
|
|
129
|
+
created: (m) => console.log(m),
|
|
130
|
+
out: (m) => console.log(m)
|
|
131
|
+
};
|
|
132
|
+
async function runBuild() {
|
|
133
|
+
process.env.NODE_ENV = "production";
|
|
134
|
+
if (isSilent) {
|
|
135
|
+
process.env.FLAME_BUILD_SILENT = "1";
|
|
136
|
+
process.env.LOG_LEVEL = "error";
|
|
137
|
+
}
|
|
138
|
+
const { runBuildCli } = await import("./build.impl-CtPrlYAE.js");
|
|
139
|
+
await runBuildCli();
|
|
140
|
+
}
|
|
141
|
+
async function writeDockerFiles() {
|
|
142
|
+
const dockerDir = PROJECT_ROOT;
|
|
143
|
+
if (!existsSync(join(dockerDir, "Dockerfile"))) {
|
|
144
|
+
await writeFile(join(dockerDir, "Dockerfile"), `FROM ghcr.io/docubook/flame:${FLAME_MAJOR} AS builder
|
|
145
|
+
ENV NODE_ENV=production
|
|
146
|
+
WORKDIR /app
|
|
147
|
+
COPY . .
|
|
148
|
+
RUN flame build
|
|
149
|
+
|
|
150
|
+
FROM nginx:alpine
|
|
151
|
+
COPY --from=builder /app/.docu/dist /usr/share/nginx/html
|
|
152
|
+
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
153
|
+
EXPOSE 80
|
|
154
|
+
CMD ["nginx", "-g", "daemon off;"]
|
|
155
|
+
`);
|
|
156
|
+
log.created("📄 Created Dockerfile");
|
|
157
|
+
}
|
|
158
|
+
if (!existsSync(join(dockerDir, "nginx.conf"))) {
|
|
159
|
+
await writeFile(join(dockerDir, "nginx.conf"), NGINX_CONF);
|
|
160
|
+
log.created("📄 Created nginx.conf");
|
|
161
|
+
}
|
|
162
|
+
if (!existsSync(join(dockerDir, ".dockerignore"))) {
|
|
163
|
+
await writeFile(join(dockerDir, ".dockerignore"), DOCKERIGNORE);
|
|
164
|
+
log.created("📄 Created .dockerignore");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function generateWorkflowYml() {
|
|
168
|
+
const pm = detectPkgManager(PROJECT_ROOT);
|
|
169
|
+
const setupSteps = [
|
|
170
|
+
" - uses: actions/checkout@v7",
|
|
171
|
+
" with:",
|
|
172
|
+
" fetch-depth: 0",
|
|
173
|
+
""
|
|
174
|
+
];
|
|
175
|
+
if (pm.setupAction === "bun") setupSteps.push(" - uses: oven-sh/setup-bun@v2", " with:", " bun-version: latest", "");
|
|
176
|
+
else if (pm.setupAction === "pnpm") setupSteps.push(" - uses: pnpm/action-setup@v6", "", " - uses: actions/setup-node@v6", " with:", " node-version: 22", ` cache: ${pm.cache}`, "");
|
|
177
|
+
else setupSteps.push(" - uses: actions/setup-node@v6", " with:", " node-version: 22", ` cache: ${pm.cache}`, "");
|
|
178
|
+
return [
|
|
179
|
+
`name: Deploy to GitHub Pages`,
|
|
180
|
+
"",
|
|
181
|
+
"on:",
|
|
182
|
+
" push:",
|
|
183
|
+
" branches: [main]",
|
|
184
|
+
" workflow_dispatch:",
|
|
185
|
+
"",
|
|
186
|
+
"permissions:",
|
|
187
|
+
" contents: read",
|
|
188
|
+
" pages: write",
|
|
189
|
+
" id-token: write",
|
|
190
|
+
"",
|
|
191
|
+
"concurrency:",
|
|
192
|
+
" group: \"pages\"",
|
|
193
|
+
" cancel-in-progress: false",
|
|
194
|
+
"",
|
|
195
|
+
"jobs:",
|
|
196
|
+
" build:",
|
|
197
|
+
" runs-on: ubuntu-latest",
|
|
198
|
+
" steps:",
|
|
199
|
+
...setupSteps,
|
|
200
|
+
` - run: ${pm.installCmd}`,
|
|
201
|
+
"",
|
|
202
|
+
` - run: ${pm.runCmd} 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
|
+
].join("\n");
|
|
221
|
+
}
|
|
222
|
+
function generateDockerWorkflowYml() {
|
|
223
|
+
return [
|
|
224
|
+
`name: Build & Push Docker Image`,
|
|
225
|
+
"",
|
|
226
|
+
"on:",
|
|
227
|
+
" push:",
|
|
228
|
+
" branches: [main]",
|
|
229
|
+
" workflow_dispatch:",
|
|
230
|
+
"",
|
|
231
|
+
"permissions:",
|
|
232
|
+
" contents: read",
|
|
233
|
+
" packages: write",
|
|
234
|
+
"",
|
|
235
|
+
"jobs:",
|
|
236
|
+
" build:",
|
|
237
|
+
" runs-on: ubuntu-latest",
|
|
238
|
+
" steps:",
|
|
239
|
+
" - uses: actions/checkout@v4",
|
|
240
|
+
" with:",
|
|
241
|
+
" fetch-depth: 0",
|
|
242
|
+
"",
|
|
243
|
+
" - name: Log in to GHCR",
|
|
244
|
+
" uses: docker/login-action@v3",
|
|
245
|
+
" with:",
|
|
246
|
+
" registry: ghcr.io",
|
|
247
|
+
" username: ${{ github.actor }}",
|
|
248
|
+
" password: ${{ secrets.GITHUB_TOKEN }}",
|
|
249
|
+
"",
|
|
250
|
+
" - name: Build & push",
|
|
251
|
+
" uses: docker/build-push-action@v5",
|
|
252
|
+
" with:",
|
|
253
|
+
" context: .",
|
|
254
|
+
` tags: ghcr.io/\${{ github.repository }}:latest`,
|
|
255
|
+
" push: true"
|
|
256
|
+
].join("\n");
|
|
257
|
+
}
|
|
258
|
+
async function writeGhaWorkflow() {
|
|
259
|
+
if (!existsSync(WORKFLOW_FILE)) {
|
|
260
|
+
await mkdir(WORKFLOW_DIR, { recursive: true });
|
|
261
|
+
await writeFile(WORKFLOW_FILE, generateWorkflowYml());
|
|
262
|
+
log.created("📄 Created .github/workflows/deploy.yml");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
var DOCKER_WORKFLOW_FILE = join(WORKFLOW_DIR, "deploy-docker.yml");
|
|
266
|
+
async function writeDockerWorkflow() {
|
|
267
|
+
if (!existsSync(DOCKER_WORKFLOW_FILE)) {
|
|
268
|
+
await mkdir(WORKFLOW_DIR, { recursive: true });
|
|
269
|
+
await writeFile(DOCKER_WORKFLOW_FILE, generateDockerWorkflowYml());
|
|
270
|
+
log.created("📄 Created .github/workflows/deploy-docker.yml");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async function runDeploy() {
|
|
274
|
+
log.info("📦 Building for production...\n");
|
|
275
|
+
await runBuild();
|
|
276
|
+
await writeFile(join(DIST_DIR, ".nojekyll"), "");
|
|
277
|
+
await writeFile(join(DIST_DIR, "_headers"), HEADERS_FILE);
|
|
278
|
+
if (isDocker) {
|
|
279
|
+
await writeDockerFiles();
|
|
280
|
+
if (isCi) await writeDockerWorkflow();
|
|
281
|
+
} else await writeGhaWorkflow();
|
|
282
|
+
log.ok();
|
|
283
|
+
log.out(" Output: .docu/dist/");
|
|
284
|
+
if (isDocker) {
|
|
285
|
+
log.out(" Build locally: docker build -t my-docs . && docker run -p 80:80 my-docs");
|
|
286
|
+
if (isCi) {
|
|
287
|
+
log.out(" Push to GitHub — CI will build & push Docker image to GHCR");
|
|
288
|
+
log.out(" Then pull latest image on your hosting platform (Coolify, etc.)");
|
|
289
|
+
} else log.out(" For Coolify: connect repo, set build pack to Dockerfile");
|
|
290
|
+
} else log.out(" Push to GitHub and enable Pages (Settings → Pages → Source: GitHub Actions)");
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
293
|
+
export { runDeploy as t };
|
|
294
|
+
|
|
295
|
+
//# sourceMappingURL=deploy.shared-fk8eM-r4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.shared-fk8eM-r4.js","names":[],"sources":["../node/deploy.shared.ts"],"sourcesContent":["/**\n * Runtime-neutral deploy — 3 modes:\n * 1. `flame deploy` → build + generate GitHub Actions workflow\n * 2. `flame deploy --docker` → build + generate Docker deployment files\n * 3. `flame deploy --docker --silent` → same as #2, minimal output\n *\n * Mirror of deploy.ts (Bun-only, protected) for Node.js and Deno.\n * Runs the neutral build in-process, then prepares .docu/dist.\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { DIST_DIR, PROJECT_ROOT, FRAMEWORK_ROOT } from \"./paths\";\n\nconst FLAME_MAJOR = JSON.parse(\n readFileSync(resolve(FRAMEWORK_ROOT, \"package.json\"), \"utf-8\")\n).version.split(\".\")[0];\n\nconst WORKFLOW_DIR = join(PROJECT_ROOT, \".github/workflows\");\nconst WORKFLOW_FILE = join(WORKFLOW_DIR, \"deploy.yml\");\n\nexport const NGINX_CONF = `server {\n listen 80;\n server_name _;\n root /usr/share/nginx/html;\n index index.html;\n\n gzip on;\n gzip_types text/html text/css application/javascript image/svg+xml;\n\n # Security headers (HSTS effective when HTTPS is terminated upstream)\n add_header X-Frame-Options \"DENY\" always;\n add_header X-Content-Type-Options \"nosniff\" always;\n add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains\" always;\n add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n add_header Permissions-Policy \"camera=(), microphone=(), geolocation=()\" always;\n add_header Content-Security-Policy \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'\" always;\n\n location /assets/ {\n expires 1y;\n add_header Cache-Control \"public, immutable\";\n add_header X-Frame-Options \"DENY\" always;\n add_header X-Content-Type-Options \"nosniff\" always;\n add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains\" always;\n add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n add_header Permissions-Policy \"camera=(), microphone=(), geolocation=()\" always;\n add_header Content-Security-Policy \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'\" always;\n }\n\n location /docs/assets/ {\n expires 7d;\n add_header Cache-Control \"public\";\n add_header X-Frame-Options \"DENY\" always;\n add_header X-Content-Type-Options \"nosniff\" always;\n add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains\" always;\n add_header Referrer-Policy \"strict-origin-when-cross-origin\" always;\n add_header Permissions-Policy \"camera=(), microphone=(), geolocation=()\" always;\n add_header Content-Security-Policy \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'\" always;\n }\n\n location / {\n try_files $uri $uri.html $uri/ =404;\n }\n}\n`;\n\nexport const DOCKERIGNORE = `node_modules\n*.DS_Store\n.docu/dist\n.docu/lib\n.env\n.env.*\n.npmrc\n*.log\n`;\n\nexport function detectPkgManager(dir: string): {\n baseImage: string;\n lockFile: string;\n installCmd: string;\n runCmd: string;\n cache: string;\n setupAction: string;\n} {\n const bunLockFile = existsSync(join(dir, \"bun.lock\"))\n ? \"bun.lock\"\n : existsSync(join(dir, \"bun.lockb\"))\n ? \"bun.lockb\"\n : null;\n if (bunLockFile) {\n return {\n baseImage: \"oven/bun:1-debian\",\n lockFile: bunLockFile,\n installCmd: \"bun install --frozen-lockfile\",\n runCmd: \"bun\",\n cache: \"\",\n setupAction: \"bun\",\n };\n }\n if (existsSync(join(dir, \"pnpm-lock.yaml\"))) {\n return {\n baseImage: \"node:22-alpine\",\n lockFile: \"pnpm-lock.yaml\",\n installCmd: \"corepack enable && pnpm install --frozen-lockfile\",\n runCmd: \"pnpm\",\n cache: \"pnpm\",\n setupAction: \"pnpm\",\n };\n }\n if (existsSync(join(dir, \"yarn.lock\"))) {\n return {\n baseImage: \"node:22-alpine\",\n lockFile: \"yarn.lock\",\n installCmd: \"yarn install --frozen-lockfile\",\n runCmd: \"yarn\",\n cache: \"yarn\",\n setupAction: \"node\",\n };\n }\n // default: npm\n return {\n baseImage: \"node:22-alpine\",\n lockFile: \"package-lock.json\",\n installCmd: \"npm ci\",\n runCmd: \"npm\",\n cache: \"npm\",\n setupAction: \"node\",\n };\n}\n\nexport const HEADERS_FILE = `/*\n X-Frame-Options: DENY\n X-Content-Type-Options: nosniff\n Strict-Transport-Security: max-age=63072000; includeSubDomains; preload\n Referrer-Policy: strict-origin-when-cross-origin\n Permissions-Policy: camera=(), microphone=(), geolocation=()\n Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data:; font-src 'self' data:; connect-src 'self' https:; frame-src https://www.youtube-nocookie.com; frame-ancestors 'none'\n\n/assets/*\n Cache-Control: public, max-age=31536000, immutable\n`;\n\nconst isDocker = !!process.env.FLAME_DEPLOY_DOCKER;\nconst isSilent = !!process.env.FLAME_DEPLOY_SILENT;\nconst isCi = !!process.env.FLAME_DEPLOY_CI;\n\n/** Logger that no-ops all non-error output in silent mode. */\nconst log = isSilent\n ? { info: () => {}, ok: () => {}, created: () => {}, out: () => {} }\n : {\n info: (m: string) => console.log(m),\n ok: () => console.log(\"\\n✅ Ready to deploy!\"),\n created: (m: string) => console.log(m),\n out: (m: string) => console.log(m),\n };\n\nasync function runBuild() {\n process.env.NODE_ENV = \"production\";\n if (isSilent) {\n process.env.FLAME_BUILD_SILENT = \"1\";\n process.env.LOG_LEVEL = \"error\";\n }\n const { runBuildCli } = await import(\"./build.impl\");\n await runBuildCli();\n}\n\nasync function writeDockerFiles() {\n const dockerDir = PROJECT_ROOT;\n\n if (!existsSync(join(dockerDir, \"Dockerfile\"))) {\n await writeFile(\n join(dockerDir, \"Dockerfile\"),\n `FROM ghcr.io/docubook/flame:${FLAME_MAJOR} AS builder\nENV NODE_ENV=production\nWORKDIR /app\nCOPY . .\nRUN flame build\n\nFROM nginx:alpine\nCOPY --from=builder /app/.docu/dist /usr/share/nginx/html\nCOPY nginx.conf /etc/nginx/conf.d/default.conf\nEXPOSE 80\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n`\n );\n log.created(\"📄 Created Dockerfile\");\n }\n\n if (!existsSync(join(dockerDir, \"nginx.conf\"))) {\n await writeFile(join(dockerDir, \"nginx.conf\"), NGINX_CONF);\n log.created(\"📄 Created nginx.conf\");\n }\n\n if (!existsSync(join(dockerDir, \".dockerignore\"))) {\n await writeFile(join(dockerDir, \".dockerignore\"), DOCKERIGNORE);\n log.created(\"📄 Created .dockerignore\");\n }\n}\n\nfunction generateWorkflowYml(): string {\n const pm = detectPkgManager(PROJECT_ROOT);\n\n const setupSteps: string[] = [\n \" - uses: actions/checkout@v7\",\n \" with:\",\n \" fetch-depth: 0\",\n \"\",\n ];\n\n if (pm.setupAction === \"bun\") {\n setupSteps.push(\n \" - uses: oven-sh/setup-bun@v2\",\n \" with:\",\n \" bun-version: latest\",\n \"\"\n );\n } else if (pm.setupAction === \"pnpm\") {\n setupSteps.push(\n \" - uses: pnpm/action-setup@v6\",\n \"\",\n \" - uses: actions/setup-node@v6\",\n \" with:\",\n \" node-version: 22\",\n ` cache: ${pm.cache}`,\n \"\"\n );\n } else {\n // npm / yarn\n setupSteps.push(\n \" - uses: actions/setup-node@v6\",\n \" with:\",\n \" node-version: 22\",\n ` cache: ${pm.cache}`,\n \"\"\n );\n }\n\n return [\n `name: Deploy to GitHub Pages`,\n \"\",\n \"on:\",\n \" push:\",\n \" branches: [main]\",\n \" workflow_dispatch:\",\n \"\",\n \"permissions:\",\n \" contents: read\",\n \" pages: write\",\n \" id-token: write\",\n \"\",\n \"concurrency:\",\n ' group: \"pages\"',\n \" cancel-in-progress: false\",\n \"\",\n \"jobs:\",\n \" build:\",\n \" runs-on: ubuntu-latest\",\n \" steps:\",\n ...setupSteps,\n ` - run: ${pm.installCmd}`,\n \"\",\n ` - run: ${pm.runCmd} run build`,\n \"\",\n \" - name: Add .nojekyll\",\n \" run: touch .docu/dist/.nojekyll\",\n \"\",\n \" - uses: actions/upload-pages-artifact@v3\",\n \" with:\",\n \" path: .docu/dist\",\n \"\",\n \" deploy:\",\n \" environment:\",\n \" name: github-pages\",\n \" url: ${{ steps.deployment.outputs.page_url }}\",\n \" runs-on: ubuntu-latest\",\n \" needs: build\",\n \" steps:\",\n \" - id: deployment\",\n \" uses: actions/deploy-pages@v4\",\n ].join(\"\\n\");\n}\n\nfunction generateDockerWorkflowYml(): string {\n const imageName = \"ghcr.io/${{ github.repository }}\";\n return [\n `name: Build & Push Docker Image`,\n \"\",\n \"on:\",\n \" push:\",\n \" branches: [main]\",\n \" workflow_dispatch:\",\n \"\",\n \"permissions:\",\n \" contents: read\",\n \" packages: write\",\n \"\",\n \"jobs:\",\n \" build:\",\n \" runs-on: ubuntu-latest\",\n \" steps:\",\n \" - uses: actions/checkout@v4\",\n \" with:\",\n \" fetch-depth: 0\",\n \"\",\n \" - name: Log in to GHCR\",\n \" uses: docker/login-action@v3\",\n \" with:\",\n \" registry: ghcr.io\",\n \" username: ${{ github.actor }}\",\n \" password: ${{ secrets.GITHUB_TOKEN }}\",\n \"\",\n \" - name: Build & push\",\n \" uses: docker/build-push-action@v5\",\n \" with:\",\n \" context: .\",\n ` tags: ${imageName}:latest`,\n \" push: true\",\n ].join(\"\\n\");\n}\n\nasync function writeGhaWorkflow() {\n if (!existsSync(WORKFLOW_FILE)) {\n await mkdir(WORKFLOW_DIR, { recursive: true });\n await writeFile(WORKFLOW_FILE, generateWorkflowYml());\n log.created(\"📄 Created .github/workflows/deploy.yml\");\n }\n}\n\nconst DOCKER_WORKFLOW_FILE = join(WORKFLOW_DIR, \"deploy-docker.yml\");\n\nasync function writeDockerWorkflow() {\n if (!existsSync(DOCKER_WORKFLOW_FILE)) {\n await mkdir(WORKFLOW_DIR, { recursive: true });\n await writeFile(DOCKER_WORKFLOW_FILE, generateDockerWorkflowYml());\n log.created(\"📄 Created .github/workflows/deploy-docker.yml\");\n }\n}\n\nexport async function runDeploy(): Promise<void> {\n log.info(\"📦 Building for production...\\n\");\n await runBuild();\n\n // Common: .nojekyll + _headers\n await writeFile(join(DIST_DIR, \".nojekyll\"), \"\");\n await writeFile(join(DIST_DIR, \"_headers\"), HEADERS_FILE);\n\n if (isDocker) {\n await writeDockerFiles();\n if (isCi) await writeDockerWorkflow();\n } else {\n await writeGhaWorkflow();\n }\n\n log.ok();\n log.out(\" Output: .docu/dist/\");\n if (isDocker) {\n log.out(\" Build locally: docker build -t my-docs . && docker run -p 80:80 my-docs\");\n if (isCi) {\n log.out(\" Push to GitHub — CI will build & push Docker image to GHCR\");\n log.out(\" Then pull latest image on your hosting platform (Coolify, etc.)\");\n } else {\n log.out(\" For Coolify: connect repo, set build pack to Dockerfile\");\n }\n } else {\n log.out(\" Push to GitHub and enable Pages (Settings → Pages → Source: GitHub Actions)\");\n }\n}\n"],"mappings":"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"}
|