diff --git a/packages/core/package.json b/packages/core/package.json index 1af4cb22d..8bb5f6703 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -40,6 +40,7 @@ "argon2": "^0.28.5", "chalk": "^4", "dayjs": "^1.10.5", + "debug": "^4.3.4", "decamelize": "^5.0.0", "deepmerge": "^4.2.2", "dotenv": "^16.0.0", @@ -54,7 +55,7 @@ "koa-mount": "^4.0.0", "koa-proxies": "^0.12.1", "koa-router": "^10.0.0", - "koa-static": "^5.0.0", + "koa-send": "^5.0.1", "lodash.pick": "^4.4.0", "module-alias": "^2.2.2", "nanoid": "^3.1.23", @@ -74,12 +75,13 @@ "@silverhand/eslint-config": "^0.14.0", "@silverhand/jest-config": "^0.14.0", "@silverhand/ts-config": "^0.14.0", + "@types/debug": "^4.1.7", "@types/inquirer": "^8.2.1", "@types/jest": "^27.4.1", "@types/koa": "^2.13.3", "@types/koa-logger": "^3.1.1", "@types/koa-mount": "^4.0.0", - "@types/koa-static": "^4.0.2", + "@types/koa-send": "^4.1.3", "@types/lodash.pick": "^4.4.6", "@types/node": "^16.3.1", "@types/oidc-provider": "^7.8.0", diff --git a/packages/core/src/middleware/koa-serve-static.ts b/packages/core/src/middleware/koa-serve-static.ts new file mode 100644 index 000000000..973add6d1 --- /dev/null +++ b/packages/core/src/middleware/koa-serve-static.ts @@ -0,0 +1,38 @@ +// Modified from https://github.com/koajs/static/blob/7f0ed88c8902e441da4e30b42f108617d8dff9ec/index.js + +import path from 'path'; + +import buildDebug from 'debug'; +import { MiddlewareType } from 'koa'; +import send from 'koa-send'; + +import assertThat from '@/utils/assert-that'; + +const debug = buildDebug('koa-static'); + +export default function serve(root: string) { + assertThat(root, new Error('Root directory is required to serve files.')); + + const options: send.SendOptions = { + root: path.resolve(root), + index: 'index.html', + }; + + debug('static "%s"', root); + + const serve: MiddlewareType = async (ctx, next) => { + if (ctx.method === 'HEAD' || ctx.method === 'GET') { + await send(ctx, ctx.path, { + ...options, + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + ...(!['/', `/${options.index || ''}`].some((path) => ctx.path.endsWith(path)) && { + maxage: 604_800_000 /* 7 days */, + }), + }); + } + + return next(); + }; + + return serve; +} diff --git a/packages/core/src/middleware/koa-spa-proxy.test.ts b/packages/core/src/middleware/koa-spa-proxy.test.ts index dd971d1b3..2ea39ead5 100644 --- a/packages/core/src/middleware/koa-spa-proxy.test.ts +++ b/packages/core/src/middleware/koa-spa-proxy.test.ts @@ -12,7 +12,7 @@ jest.mock('fs/promises', () => ({ })); jest.mock('koa-proxies', () => jest.fn(() => mockProxyMiddleware)); -jest.mock('koa-static', () => jest.fn(() => mockStaticMiddleware)); +jest.mock('@/middleware/koa-serve-static', () => jest.fn(() => mockStaticMiddleware)); describe('koaSpaProxy middleware', () => { const envBackup = process.env; diff --git a/packages/core/src/middleware/koa-spa-proxy.ts b/packages/core/src/middleware/koa-spa-proxy.ts index 44a9a99a7..1d404903b 100644 --- a/packages/core/src/middleware/koa-spa-proxy.ts +++ b/packages/core/src/middleware/koa-spa-proxy.ts @@ -4,10 +4,10 @@ import path from 'path'; import { MiddlewareType } from 'koa'; import proxy from 'koa-proxies'; import { IRouterParamContext } from 'koa-router'; -import serveStatic from 'koa-static'; import envSet, { MountedApps } from '@/env-set'; import { fromRoot } from '@/env-set/parameters'; +import serveStatic from '@/middleware/koa-serve-static'; export default function koaSpaProxy( packagePath = 'ui', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b7e45d03..2562864d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -766,12 +766,13 @@ importers: '@silverhand/essentials': ^1.1.6 '@silverhand/jest-config': ^0.14.0 '@silverhand/ts-config': ^0.14.0 + '@types/debug': ^4.1.7 '@types/inquirer': ^8.2.1 '@types/jest': ^27.4.1 '@types/koa': ^2.13.3 '@types/koa-logger': ^3.1.1 '@types/koa-mount': ^4.0.0 - '@types/koa-static': ^4.0.2 + '@types/koa-send': ^4.1.3 '@types/lodash.pick': ^4.4.6 '@types/node': ^16.3.1 '@types/oidc-provider': ^7.8.0 @@ -780,6 +781,7 @@ importers: chalk: ^4 copyfiles: ^2.4.1 dayjs: ^1.10.5 + debug: ^4.3.4 decamelize: ^5.0.0 deepmerge: ^4.2.2 dotenv: ^16.0.0 @@ -797,7 +799,7 @@ importers: koa-mount: ^4.0.0 koa-proxies: ^0.12.1 koa-router: ^10.0.0 - koa-static: ^5.0.0 + koa-send: ^5.0.1 lint-staged: ^12.0.0 lodash.pick: ^4.4.0 module-alias: ^2.2.2 @@ -841,6 +843,7 @@ importers: argon2: 0.28.5 chalk: 4.1.2 dayjs: 1.10.7 + debug: 4.3.4 decamelize: 5.0.1 deepmerge: 4.2.2 dotenv: 16.0.0 @@ -853,9 +856,9 @@ importers: koa-body: 5.0.0 koa-logger: 3.2.1 koa-mount: 4.0.0 - koa-proxies: 0.12.1_koa@2.13.4 + koa-proxies: 0.12.1_debug@4.3.4+koa@2.13.4 koa-router: 10.1.1 - koa-static: 5.0.0 + koa-send: 5.0.1 lodash.pick: 4.4.0 module-alias: 2.2.2 nanoid: 3.1.30 @@ -874,12 +877,13 @@ importers: '@silverhand/eslint-config': 0.14.0_hjjt7jwmhwqm7bjf55k5ihcdqq '@silverhand/jest-config': 0.14.0_makj2rl6gt73u7koqro542qsmm '@silverhand/ts-config': 0.14.0_typescript@4.6.2 + '@types/debug': 4.1.7 '@types/inquirer': 8.2.1 '@types/jest': 27.4.1 '@types/koa': 2.13.4 '@types/koa-logger': 3.1.2 '@types/koa-mount': 4.0.1 - '@types/koa-static': 4.0.2 + '@types/koa-send': 4.1.3 '@types/lodash.pick': 4.4.6 '@types/node': 16.11.12 '@types/oidc-provider': 7.8.1 @@ -7518,13 +7522,6 @@ packages: '@types/koa': 2.13.4 dev: true - /@types/koa-static/4.0.2: - resolution: {integrity: sha512-ns/zHg+K6XVPMuohjpOlpkR1WLa4VJ9czgUP9bxkCDn0JZBtUWbD/wKDZzPGDclkQK1bpAEScufCHOy8cbfL0w==} - dependencies: - '@types/koa': 2.13.4 - '@types/koa-send': 4.1.3 - dev: true - /@types/koa/2.13.4: resolution: {integrity: sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==} dependencies: @@ -10395,6 +10392,7 @@ packages: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} dependencies: ms: 2.1.3 + dev: true /debug/4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} @@ -10406,6 +10404,7 @@ packages: optional: true dependencies: ms: 2.1.2 + dev: true /debug/4.3.3_supports-color@9.2.2: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} @@ -11881,6 +11880,19 @@ packages: peerDependenciesMeta: debug: optional: true + dev: true + + /follow-redirects/1.14.6_debug@4.3.4: + resolution: {integrity: sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dependencies: + debug: 4.3.4 + dev: false /follow-redirects/1.14.9: resolution: {integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==} @@ -12879,6 +12891,18 @@ packages: requires-port: 1.0.0 transitivePeerDependencies: - debug + dev: true + + /http-proxy/1.18.1_debug@4.3.4: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.14.6_debug@4.3.4 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: false /http2-wrapper/1.0.3: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} @@ -14461,18 +14485,18 @@ packages: resolution: {integrity: sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ==} engines: {node: '>= 7.6.0'} dependencies: - debug: 4.3.3 + debug: 4.3.4 koa-compose: 4.1.0 transitivePeerDependencies: - supports-color dev: false - /koa-proxies/0.12.1_koa@2.13.4: + /koa-proxies/0.12.1_debug@4.3.4+koa@2.13.4: resolution: {integrity: sha512-qCOGY7Qoe/Ewn2VskP9TdLMZffmsv8JUBWllNlmTJmgl1059nxt5jl7QBWNniqx2BthVSU5TIBuhUULA5d6t+A==} peerDependencies: koa: '>=2' dependencies: - http-proxy: 1.18.1 + http-proxy: 1.18.1_debug@4.3.4 koa: 2.13.4 path-match: 1.2.4 transitivePeerDependencies: @@ -14483,7 +14507,7 @@ packages: resolution: {integrity: sha512-z/OzxVjf5NyuNO3t9nJpx7e1oR3FSBAauiwXtMQu4ppcnuNZzTaQ4p21P8A6r2Es8uJJM339oc4oVW+qX7SqnQ==} engines: {node: '>= 8.0.0'} dependencies: - debug: 4.3.3 + debug: 4.3.4 http-errors: 1.8.1 koa-compose: 4.1.0 methods: 1.1.2 @@ -14496,23 +14520,13 @@ packages: resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==} engines: {node: '>= 8'} dependencies: - debug: 4.3.3 + debug: 4.3.4 http-errors: 1.8.1 resolve-path: 1.4.0 transitivePeerDependencies: - supports-color dev: false - /koa-static/5.0.0: - resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==} - engines: {node: '>= 7.6.0'} - dependencies: - debug: 3.2.7 - koa-send: 5.0.1 - transitivePeerDependencies: - - supports-color - dev: false - /koa/2.13.4: resolution: {integrity: sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} @@ -14522,7 +14536,7 @@ packages: content-disposition: 0.5.4 content-type: 1.0.4 cookies: 0.8.0 - debug: 4.3.3 + debug: 4.3.4 delegates: 1.0.0 depd: 2.0.0 destroy: 1.0.4 @@ -15782,6 +15796,7 @@ packages: /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true /msgpackr-extract/1.0.16: resolution: {integrity: sha512-fxdRfQUxPrL/TizyfYfMn09dK58e+d65bRD/fcaVH4052vj30QOzzqxcQIS7B0NsqlypEQ/6Du3QmP2DhWFfCA==} @@ -16287,7 +16302,7 @@ packages: dependencies: '@koa/cors': 3.1.0 cacheable-lookup: 6.0.4 - debug: 4.3.3 + debug: 4.3.4 ejs: 3.1.6 got: 11.8.3 jose: 4.6.0