include admin and frontend inside the exe
Massimo Melina committed
Feb 9, 2022 at 22:55 UTC
e8ad7d6e66c8b6364abc8a59d8551432515441aa
4 files changed
+24
-24
package-lock.json
+2
-2
@@ -1,12 +1,12 @@
1
{
2
"name": "hfs",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
"lockfileVersion": 2,
5
"requires": true,
6
"packages": {
7
"": {
8
"name": "hfs",
9
- "version": "0.9.1",
9
+ "version": "0.10.0",
10
"license": "GPL-3.0",
11
"dependencies": {
12
"@koa/router": "^10.1.1",
package.json
+6
-7
@@ -1,6 +1,6 @@
1
{
2
"name": "hfs",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
"description": "HTTP File Server",
5
"keywords": [
6
"file server",
@@ -20,12 +20,9 @@
20
"build-admin": "cd admin && npm install && npm run build",
21
"test": "mocha -r ts-node/register 'tests/**/*.ts'",
22
"zip-dist": "cd dist && zip hfs.zip -r * -x *.zip *.exe",
23
- "exe-dist": "pkg . -C brotli && cd dist && rm -rf src node_modules && zip hfs.exe.zip -r * -x *.zip run.bat",
23
+ "exe-dist": "pkg . -C brotli && cd dist && zip hfs.exe.zip hfs.exe -r plugins",
24
"new-dist": "npm run build-all && npm run zip-dist && npm run exe-dist"
25
},
26
- "bin": {
27
- "hfs": "./dist/src/index.js"
28
- },
26
"engines": {
27
"node": ">=16.13.0"
28
},
@@ -36,9 +33,11 @@
33
"type": "git",
34
"url": "https://github.com/rejetto/hfs/"
35
},
36
+ "bin": {
37
+ "hfs": "dist/src/index.js"
38
+ },
39
"pkg": {
40
- "scripts": "dist/src/**/*.js",
41
- "assets": "",
40
+ "assets": ["dist/admin/**/*", "dist/frontend/**/*"],
41
"targets": [
42
"node16-win"
43
],
src/serveFile.ts
+3
-2
@@ -1,5 +1,5 @@
1
import Koa from 'koa'
2
-import { createReadStream } from 'fs'
2
+import { createReadStream, stat } from 'fs'
3
import fs from 'fs/promises'
4
import { METHOD_NOT_ALLOWED, NO_CONTENT } from './const'
5
import { MIME_AUTO, VfsNode } from './vfs'
@@ -8,6 +8,7 @@ import { getConfig } from './config'
8
import mm from 'micromatch'
9
import _ from 'lodash'
10
import path from 'path'
11
+import { promisify } from 'util'
12
13
export function serveFileNode(node: VfsNode) : Koa.Middleware {
14
const { source, mime } = node
@@ -37,7 +38,7 @@ export function serveFile(source:string, mime?:string, modifier?:(s:string)=>str
38
}
39
if (ctx.method !== 'GET')
40
return ctx.status = METHOD_NOT_ALLOWED
40
- const stats = await fs.stat(source)
41
+ const stats = await promisify(stat)(source) // using fs's function instead of fs/promises, because only the former is supported by pkg
42
ctx.set('Last-Modified', stats.mtime.toUTCString())
43
ctx.fileSource = source
44
ctx.status = 200
src/serveFrontend.ts
+13
-13
@@ -5,6 +5,7 @@ import { serveFile } from './serveFile'
5
import { mapPlugins } from './plugins'
6
import { refresh_session } from './api.auth'
7
import { ApiError } from './apis'
8
+import path from 'path'
9
10
function serveProxyFrontend(port?: string) { // used for development
11
if (!port)
@@ -30,26 +31,25 @@ function serveProxyFrontend(port?: string) { // used for development
31
const DEV_STATIC = process.env.DEV ? 'dist/' : ''
32
33
const serveStaticFrontend : Koa.Middleware = async (ctx, next) => {
33
- const BASE = DEV_STATIC + 'frontend/'
34
- let { path, method } = ctx
35
- if (method === 'OPTIONS') {
34
+ const isDir = ctx.path.endsWith('/')
35
+ const fullPath = path.join(__dirname, '..', DEV_STATIC, 'frontend', isDir ? '/index.html' : ctx.path)
36
+ if (ctx.method === 'OPTIONS') {
37
ctx.status = NO_CONTENT
38
ctx.set({ Allow: 'OPTIONS, GET' })
39
return
40
}
40
- if (method !== 'GET')
41
+ if (ctx.method !== 'GET')
42
return ctx.status = METHOD_NOT_ALLOWED
42
- if (path.endsWith('/')) { // we don't cache the index as it's small and may prevent plugins change to apply
43
- ctx.body = await treatIndex(ctx, String(await fs.readFile(BASE + 'index.html')))
44
- ctx.type = 'html'
45
- ctx.set('Cache-Control', 'no-store, no-cache, must-revalidate')
46
- } else {
47
- const fullPath = BASE + path.slice(1)
48
- const modifier = path.includes('static/js') ? // webpack
43
+ if (!isDir) {
44
+ const modifier = fullPath.includes('static/js') ? // webpack
45
(s:string) => s.replace(/(return")(static\/)/g, '$1' + FRONTEND_URI.substring(1) + '$2')
46
: undefined
47
return serveFile(fullPath, 'auto', modifier)(ctx, next)
48
}
49
+ // we don't cache the index as it's small and may prevent plugins change to apply
50
+ ctx.body = await treatIndex(ctx, String(await fs.readFile(fullPath)))
51
+ ctx.type = 'html'
52
+ ctx.set('Cache-Control', 'no-store, no-cache, must-revalidate')
53
await next()
54
}
55
@@ -66,8 +66,8 @@ function serveAdminProxy(port?: string) { // used for development
66
}
67
68
const serveAdminStatic : Koa.Middleware = async (ctx, next) => {
69
- const fullPath = 'admin' + (ctx.path.includes('.') ? ctx.path : '/index.html');
70
- return serveFile(DEV_STATIC + fullPath, 'auto')(ctx, next)
69
+ const fullPath = path.join(__dirname, '..', DEV_STATIC, 'admin', ctx.path.includes('.') ? ctx.path : '/index.html')
70
+ return serveFile(fullPath, 'auto')(ctx, next)
71
}
72
73
async function treatIndex(ctx: Koa.Context, body: string) {