Git Product home page Git Product logo

serve-static's People

Contributors

abstractcoder avatar beeman avatar caucik avatar dependabot[bot] avatar geekdada avatar kamilmysliwiec avatar kamronbatman avatar micalevisk avatar pong420 avatar renovate-bot avatar renovate[bot] avatar taosher avatar tomastrajan avatar tony133 avatar wodcz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

serve-static's Issues

allow multi-root serving


[ ] Regression 
[ ] Bug report
[ x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

The forRoot module only allows for a single top-level directory.

Expected behavior

It would be able to specify multiple paths. This would allow multiple, static sites to be hosted by the same Nest applications.

What is the motivation / use case for changing the behavior?

Serve more than one static site using the same instance of Nest/Serve-static

Nest can't resolve dependencies of the ServeStaticModule

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

I have a pre-configured module I built ...

import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from "node:path";

@Module({
    imports: [
        ServeStaticModule.forRoot({
            rootPath: join(process.cwd(), '..', 'client', 'dist')
        })
    ],
    exports: [
        ServeStaticModule
    ]
})
export class ClientStaticModule { }

Tests all pass...

import { INestApplication } from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import { ServeStaticModule } from './client.module';

describe('ClientModule', () => {
    let app: INestApplication;

    it('should be defined', async () => {
        const moduleRef = await Test.createTestingModule({
            imports: [ServeStaticModule.registerAsync()]
        }).compile();

        app = moduleRef.createNestApplication();
        await app.init();

        expect(moduleRef.get(HttpAdapterHost)).toBeInstanceOf(HttpAdapterHost);
    });

    afterAll(async () => {
        await app.close();
    })
});

But when importing this into my other project it throws an error.

Error

[Nest] 6704  - 11/17/2023, 8:49:58 PM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the ServeStaticModule (SERVE_STATIC_MODULE_OPTIONS, AbstractLoader, ?). Please make sure that the argument HttpAdapterHost at index [2] is available in the ServeStaticModule context.

Potential solutions:
- Is ServeStaticModule a valid NestJS module?
- If HttpAdapterHost is a provider, is it part of the current ServeStaticModule?
- If HttpAdapterHost is exported from a separate @Module, is that module imported within ServeStaticModule?
  @Module({
    imports: [ /* the Module containing HttpAdapterHost */ ]
  })

Error: Nest can't resolve dependencies of the ServeStaticModule (SERVE_STATIC_MODULE_OPTIONS, AbstractLoader, ?). Please make sure that the argument HttpAdapterHost at index [2] is available in the ServeStaticModule context.

Potential solutions:
- Is ServeStaticModule a valid NestJS module?
- If HttpAdapterHost is a provider, is it part of the current ServeStaticModule?
- If HttpAdapterHost is exported from a separate @Module, is that module imported within ServeStaticModule?
  @Module({
    imports: [ /* the Module containing HttpAdapterHost */ ]
  })

    at Injector.lookupComponentInParentModules (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:254:19)
    at Injector.resolveComponentInstance (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:207:33)
    at resolveParam (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:128:38)
    at async Promise.all (index 2)
    at Injector.resolveConstructorParams (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:143:27)
    at Injector.loadInstance (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:70:13)
    at Injector.loadProvider (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/injector.js:97:9)
    at /workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/instance-loader.js:56:13
    at async Promise.all (index 0)
    at InstanceLoader.createInstancesOfProviders (/workspace/.yarn/unplugged/@nestjs-core-virtual-38511f33b2/node_modules/@nestjs/core/injector/instance-loader.js:55:9)

I've seen this on StackOverflow too... and I've checked the @nest/core and @nest/common versions and they are all the same...
I even set my yarn "resolutions" to ensure the correct verion

"resolutions": {
    "@nestjs/common": "10.2.9",
    "@nestjs/core": "10.2.9",
    "@nestjs/platform-express": "10.2.9"
  }

Minimum reproduction code

I cant link to an enterprise applicaiton

Steps to reproduce

No response

Expected behavior

The import to work when run

Package version

10.2.9

NestJS version

10.2.1

Node.js version

20.9.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Index not working in serveStaticOptions

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior


ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', '.well-known/apple-app-site-association'),
      serveStaticOptions: { index: ['index.json'] },
}),

The code above does still not work if index.html is not available.

Expected behavior

I want to serve the JSON file instead of HTML.

What is the motivation / use case for changing the behavior?

I need apple app site association file for the deep-linking iOS app with my backend.

Environment


Nest version: 6.11.11

 
For Tooling issues:
- Node version: 10.12.18  
- Platform: Linux 

Serve static can't handle globalprefix

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Using the '@nestjs/serve-static' package and serving my static html file with it. After I set up the global prefix to my application, I can not reach my served root as I expected.

I couldn't find any documention/post about this issue.

As we can see from the images:
373394859_1752662201862145_7510347445378926788_n
375756412_173095079157796_5166660945827428272_n
372338699_1029157971842881_6046141653439077612_n
375006759_687657920060866_2952145945393382611_n
375237593_6671848689524906_9201333091414580869_n

Tested with Fastify and Express as well, doesn't seem to work with either of them.

Minimum reproduction code

https://github.com/Bidghur/static-serve-issue

Steps to reproduce

  1. npm i
  2. npm run start
  3. try to hit http://localhost:3000/globalprefix/static/example endpoint, should get a 404

Expected behavior

When I hit http://localhost:3000/globalprefix/static/example I should receive my static assets.

So the globalprefix should be added to my serve root path url.

Package

  • I don't know. Or some 3rd-party package
  • @nestjs/common
  • @nestjs/core
  • @nestjs/microservices
  • @nestjs/platform-express
  • @nestjs/platform-fastify
  • @nestjs/platform-socket.io
  • @nestjs/platform-ws
  • @nestjs/testing
  • @nestjs/websockets
  • Other (see below)

Other package

@nestjs/serve-static

NestJS version

9.4.3

Packages versions

    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/platform-express": "^9.0.0",
    "@nestjs/serve-static": "^4.0.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.2.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.0.0",
    "@nestjs/schematics": "^9.0.0",
    "@nestjs/testing": "^9.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "29.5.0",
    "@types/node": "18.15.11",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "29.5.0",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "29.0.5",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.2.0",
    "typescript": "^4.7.4"
  }

Node.js version

18.9.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Can't exclude the root path

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request

Current behavior

    ServeStaticModule.forRoot({
      rootPath: frontendPath,
      exclude: ['', '/', '/events'],
    }),

This config still serves my files on the base path of my application, even though i excluded it. It works correctly when calling /events.

Expected behavior

I'd expect no static serving when requesting http://localhost:4200/

Minimal reproduction of the problem with instructions

I'm using angular to render the other routes.

@Module({
  imports: [
    AngularUniversalModule.forRoot({
      bootstrap: AppServerModule,
      viewsPath: frontendPath,
      renderPath: '*',
    }),
    ServeStaticModule.forRoot({
      rootPath: frontendPath,
      exclude: ['', '/', '/events'],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})

What is the motivation / use case for changing the behavior?

I'd like my angular app to handle the root route

Option to disable the default routing on the index.html file

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I have an API that serves basic endpoints (get/post). I want to add an endpoint which serve a directory which contains files.
NestJS return an error 500 because I don't have an index.html file in the folder ...

Expected behavior

Add an option to disable the default routing on the index.html file and therefore be able to list the contents of a folder.

What is the motivation / use case for changing the behavior?

Build a basic API with get/post endpoints and also serve a directory on a custom path (for example: files uploaded or generated by the API).

Environment


Nest version: 7.0.0
@nestjs/serve-static version: 2.1.3

Serve static doesn't appear to support webpack hot reloading

I'm submitting a...

  • Regression
  • Bug report
  • Feature request
  • Documentation issue or request
  • Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Webpack hot reloading works, serve static works. I can't see any way to have them work together. That is to say - serve static with hot reloading.

Expected behavior

I would like to be able to use serve-static but with webpack hot reloading

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Global guards aren't applied for content served by this module

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

A globally registered guard isn't called before content is served by this module.

Expected behavior

Since global guards are supposed to apply to every endpoint, I'd expect them to also apply to content served by this module (at least as long as the global guard was registered by a module before the ServeStaticModule was registered), or at least for the module to have a configuration option to allow this.

Minimal reproduction of the problem with instructions

  1. Create a new Nest application, and register a global guard
  2. Add the ServeStatic module, and configure it to serve some static files.
  3. Try to access the static files - the guard won't be called.

What is the motivation / use case for changing the behavior?

I'm using Nest to write internal tooling which will be publicly accessible. I want to make sure no information is possibly leaked, so users will have to authenticate using our company-internal SSO. To implement this I created a strategy and guard and added them to the application using passport. Since the guard isn't applied to content served by this module I have two choices:

  1. Rewrite the module manually and integrate the guard into those routes (the frontend is a Vue SPA for which I do need the history fallback, making this option kinda annoying)
  2. Not use guards at all and implement the authentication completely through middleware

Right now I'm leaning more towards the latter option, but this would mean circumventing Nest's application structure, which I'd like to avoid if possible.

Environment


Nest version: 7.2.0

When build with webpack's 'production' mode - httpAdapterHost is not initialized.

Hello, I've taken your example https://github.com/nestjs/nest/tree/master/sample/24-serve-static, and added webpack builder in order to bundle everything in one file.

When build with 'production' mode set in webpack - there is an exception in runtime:

24-serve-static>npm run start:prod

> [email protected] start:prod \24-serve-static
> node dist/main

[Nest] 1736   - 02/20/2020, 2:20:43 PM   [NestFactory] Starting Nest application...
(node:1736) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
[Nest] 1736   - 02/20/2020, 2:20:43 PM   [l] l dependencies initialized +14ms
(node:1736) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getInstance' of undefined

but, if mode in webpack is commented - everything works fine.

In node_modules@nestjs\serve-static\dist\serve-static.module.js

let ServeStaticModule = ServeStaticModule_1 = class ServeStaticModule {
    constructor(ngOptions, loader, httpAdapterHost) {
        this.ngOptions = ngOptions;
        this.loader = loader;
        this.httpAdapterHost = httpAdapterHost;

httpAdapterHost in runtime is


{
  httpAdapterHost: {
    ioAdapter: null,
    globalPrefix: '',
    globalPipes: [],
    globalFilters: [],
    globalInterceptors: [],
    globalGuards: [],
    globalRequestPipes: [],
    globalRequestFilters: [],
    globalRequestInterceptors: [],
    globalRequestGuards: []
  }

see code here.
https://github.com/Serg-Mois/serve_static_webpack_bug

also, when build with webpack - you need explicitly add "fastify-static" into dependencies.

Get dynamic path

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

In some cases there is subfolders that is created dynamic. An example is a control for app based on a number.

Describe the solution you'd like

Using path routers to represent the path

        ServeStaticModule.forRoot({
            rootPath: join(__dirname, '..', 'content', 'app', ':app_ID', 'assets'),
            serveRoot: '/content/assets/:app_ID'
        }),

What is the motivation / use case for changing the behavior?

app_ID here represents the dynamic route. Give the user the choice to better represent files in some context, like control user or app files

Some properties in `serveStaticOptions` are not passed properly when Fastify is used

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

All the options other than setHeaders and redirect will not be effective if you are using Fastify as the adapter. The bug happens here https://github.com/nestjs/serve-static/blob/master/lib/loaders/fastify.loader.ts#L29 , fastify-static doesn't have an option called send (https://github.com/fastify/fastify-static/blob/master/index.js#L23).

Expected behavior

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Nest version: 7.0.8


Others:

Serve asset files

I have a question regarding the purpose of this module:

Can I use this module to serve static assets like images, videos and other miscellaneous files?

With the provided example every request maps to an index.html file inside the rootPath and I wasn't able to figure out a way to access any other file within the rootPath.

Am I missing something?

path-style versioning of static asset

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

no

Describe the solution you'd like

the idea is to have different versions for different JS files. There should be a default "latest" version for all clients not specifying a version, and versioning should be dealt with in a simple manner, like in a regular file system three. Also the number of folders and names should not be known in advance, and can be changed. example of folder structure:

  • assets/js/
    • some_js_asset/
      • latest/ --> points to v3 (example symlink)
      • 3.0/
      • 2.9/
      • 2.8/
    • some_other_unversioned_js_asset/
      • index.js --> (this would be the default "latest/") folder for this unversioned asset

and then clients would be able to fetch:

localhost/assets/js/some_js_asset --> latest
localhost/assets/js/some_js_asset/latest --> latest
localhost/assets/js/some_js_asset/3.0/ --> v3.0
localhost/assets/js/some_js_asset?version=3 --> v3.0
localhost/assets/js/some_js_asset?minVersion=2&maxVersion=3 --> v3.0
localhost/assets/js/some_other_unversioned_js_asset/ --> latest

etc ....

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

the motivation is to have a server to serve microfrontend bundles for run-time mounting. see also: https://www.youtube.com/watch?v=QHunH3MFPZs&list=PLLUD8RtHvsAOhtHnyGx57EYXoaNsxGrTU&index=5

the rootPath directory will be mounted from a dynamic volume where CI pipelines would upload the compiled JS asset without having to restart the server

The best way to set custom headers such as "Content-Security-Policy" on index.html in case it was served as a fallback for url that was not matched to static asset

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

The ServeStaticModule serves index.html in various situations

  1. /context-path - will redirect using 301 and serve idnex from /contex-path/
  2. /context-path/ - will serve index.html using express.static(clientPath, options.serveStaticOptions) so we can use setHeaders method to apply custom headers
  3. /context-path/some/path/that/falls/back/to/index - will serve index.html using app.get(renderPath, renderFn); and more preciselly res.sendFile(indexFilePath); to which the serveStaticOptions are NOT applied

Expected behavior

It would be great to be able to apply headers such as "Content-Security-Policy" on index.html undrr ALL circumstances, what would be the best way to acheive it ?

Minimal reproduction of the problem with instructions

    ServeStaticModule.forRoot({
            rootPath: join(process.cwd(), 'public'),
            serveRoot: '/context-path'
            serveStaticOptions: {
                maxAge: MAX_AGE_7_DAYS,
                etag: false,
                setHeaders: (res, path) => {  // this covers  1. and 2. situation but NOT the 3. one
                    if (path.endsWith('index.html')) {
                        res.setHeader('Cache-Control', 'no-cache');
                    }
                }
            }
        })

What is the motivation / use case for changing the behavior?

Being able to set same headers on index.html under all circumstances.

Environment


Nest version: 6.14.2

 
For Tooling issues:
- Node version: v12.13.1  
- Platform:  Windows

Others:

serveRoot doesn't work with fastify platform

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

the route set on serveRoot will return 404

Minimum reproduction code

https://github.com/ianzone/lambda-nestify/tree/serve-static

Steps to reproduce

  1. pnpm i
  2. pnpm run dev
  3. go to /client

Expected behavior

return the static site

Package version

3.0.1

NestJS version

9.3.9

Node.js version

v18.12.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

loadPackage function is duplicated from @nestjs/common

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

loadPackage is used from file lib/utils/service-static.utils.ts

Expected behavior

loadPackage should be used from @nestjs/common

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


"@nestjs/serve-static": "1.0.1"

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Error when set renderPath as regexp

I'm submitting a error when set renderPath as regexp


[ ] Regression 
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

I get the following error

/project-root/node_modules/find-my-way/index.js:356
  if (path.charCodeAt(0) !== 47) { // 47 is '/'
        ^
TypeError: path.charCodeAt is not a function

Current behavior

@Module({
  imports: [
    ServeStaticModule.forRoot({
      renderPath:
        /^\/(js|css|fonts|icons|locales|index\.html\??)\/?.+$|\/(robots\.txt|favicon\.ico)$/,
      rootPath: join(APP_ROOT_PATH, 'public'),
    }),
    ...
  controllers: [AppControllers],
})
export class AppModule {}  

## Environment

<pre><code>
Nest version: 8.0.0
 
For Tooling issues:
- Node version: v14.17.3
- Platform:  Linux

Others: @nestjs/platform-fastify 
</code></pre>

Add forRootAsync for dynamic configuration (ConfigService)

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Not implemented

Expected behavior

Same behavior than TypeOrmModule.forRootAsync(...)

ignore routes for serve-static on api endpoints

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Currently if you serveStatic alongside api routes, it would be nice if you could tell serve-static to ignore paths beginning with /api via some options. This would allow /api/not-found to return 404 from API, and not try and serve an index.html file. If there is some current way to do it, I'm also curious how I might get around this with middleware if necessary.

Expected behavior

The /api routes do not serve static on 404s.

Minimal reproduction of the problem with instructions

Run a boilerplate nestjs app with serveStatic. add app.setGlobalPrefix('api') and then try and hit /api/not-found-route-goes-here and it will serve the index.html.

What is the motivation / use case for changing the behavior?

monorepo api + webapp

Environment


Nest version: 6.12.9

 
For Tooling issues:
- Node version: v12.13.0  
- Platform: Mac  

Others:
N/A

Send correct mime-type header with served files

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

We're using this plugin to serve up the client-side app and seeing console warnings (edit: these are only warnings) because .css files served do not have the correct mime-type. I don't see an ability in the options to map file extensions to mime types in order to solve this.

Expected behavior

.css file should be served with a mime-type of text/css. I believe we should be able to map these mime types according to extension.

Minimal reproduction of the problem with instructions

image

What is the motivation / use case for changing the behavior?

Send the correct mime-types in the headers for serving static files

Environment


Nest version: 7.4.2

 
For Tooling issues:
- Node version: v12.18.3  
- Platform: Mac 

Others:

Provide a documentation how to use setHeaders function

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

In code, there is function setHeaders?: (res: any, path: string, stat: any) => any;

What is first, second and third any?

I would like to set custom headers.

Describe the solution you'd like

Describe in documentation

Not work if any controller in module has @Get('*')

ServeStaticModule not work if any controller in module has @get('*')

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Returns html content from @get('*') controller

Expected behavior

Should return asset

Minimal reproduction of the problem with instructions

@Module(
  {
    imports: [
      ServeStaticModule.forRoot(
        {
          serveRoot: '/public',
          renderPath: '/public',
          rootPath: path.resolve(__dirname, 'public/'),
          serveStaticOptions: {
            index: false,
          },
        },
      ),
    ],
    controllers: [
      FrontController,
    ],
    providers: [],
  },
)
class FrontModule {}

@Controller()
export class FrontController {
  @Get('*')
  @Accepts('html')
  index(@Res() res: Response) {
    res.send('dupa2');
  }
}

What is the motivation / use case for changing the behavior?

Environment

    "@nestjs/common": "^7.5.5",
    "@nestjs/core": "^7.5.5",
    "@nestjs/platform-express": "^7.5.5",
    "@nestjs/serve-static": "^2.1.4",

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

circleci
.circleci/config.yml
  • cimg/node 20.11
npm
package.json
  • path-to-regexp 0.2.5
  • @commitlint/cli 19.1.0
  • @commitlint/config-angular 19.1.0
  • @nestjs/common 10.3.3
  • @nestjs/core 10.3.3
  • @types/node 20.11.27
  • @typescript-eslint/eslint-plugin 7.2.0
  • @typescript-eslint/parser 7.2.0
  • eslint 8.57.0
  • eslint-config-prettier 9.1.0
  • eslint-plugin-import 2.29.1
  • express 4.18.3
  • fastify 4.26.2
  • @fastify/static 6.12.0
  • husky 9.0.11
  • lint-staged 15.2.2
  • prettier 3.2.5
  • reflect-metadata 0.2.1
  • release-it 17.1.1
  • rxjs 7.8.1
  • typescript 5.4.2
  • @nestjs/common ^9.0.0 || ^10.0.0
  • @nestjs/core ^9.0.0 || ^10.0.0
  • express ^4.18.1
  • fastify ^4.7.0
  • @fastify/static ^6.5.0

  • Check this box to trigger a request for Renovate to run again on this repository

Support `preCompressed` from `@fastify/static`

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

I have a SvelteKit app where I've set precompress: true to generate .br files. I'd like to serve them from my Nest app.

https://kit.svelte.dev/docs/adapter-static#options-precompress

Describe the solution you'd like

Support https://github.com/fastify/fastify-static?tab=readme-ov-file#precompressed

I thought from a quick glance at the source code that there was a chance the option would be passed straight through, but it didn't work in my testing.

Teachability, documentation, adoption, migration strategy

Add it to the types and docs. It's not there now.

What is the motivation / use case for changing the behavior?

Greatly improves page load time by serving brotli and gzip compressed files

Support for nestjs v9

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

I am migrating my nestjs project from v8 to v9. The fastify-static dependency in the latest version of nestjs@9 has been deprecated, and I have installed @fastify/static. The project throws the following error:

[Nest] 72982  - 2022/07/08 δΈ‹εˆ5:36:44   ERROR [PackageLoader] The "fastify-static" package is missing. Please, make sure to install this library ($ npm install fastify-static) to take advantage of ServeStaticModule.

I checked the source code of @nestjs/serve-static for the latest version(2.2.2) and found a dependency on fastify-static. Is @nestjs/serve-static being updated or scheduled to be updated. If so, when will I be able to use it?

Describe the solution you'd like

Publish updates dependent on @fastify/staticinstead.

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

Migrating nestjs from v8 to v9

Unable to turn off caching for index.html alone but leave caching enabled for other files

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

It seems that it is not possible to prevent caching of one file

Expected behavior

I would like to prevent caching of my index.html file but cache all other assets such as css and js files

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

I am serving an angular app. All generated files have a hash in the name so they care fine be cached as the name will change between versions. At the moment the index page is cached and it's very hard to get a new version loaded onto a mobile browser. Turning off caching for index.html will mean I get new app versions on mobile browsers but that the large asset files will be cached.

Missing 'prefix' property in ServeStaticOptions

ServeStaticOptions interface defined in @nestjs/platform-express has an extra property 'prefix' which is missing from the same interface defined in this package. Having the option within this module would be great and shouldn't we define the interface once unless there is a special reason for having a duplicate in this package as well?

fastify-static is deprecated use @fastify/static instead

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

A deprecated warning get triggered when we use "@nestjs/serve-static": "2.2.2"

Minimum reproduction code

https://gist.github.com/SteadEXE/2220524c25cbd59ab04ce5d772d7b56e

Steps to reproduce

  1. Create a nestjs project
  2. Add Fastify and @nestjs/serve-static
  3. Run the application.

Expected behavior

No warning in the console

Package version

2.2.2

NestJS version

8.4.5

Node.js version

16.15.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

(node:13584) [FST_MODULE_DEP_FASTIFY-STATIC] FastifyWarning.fastify-static: fastify-static has been deprecated. Use @fastify/[email protected] instead.
(Use node --trace-warnings ... to show where the warning was created)

Watсh changes in static folder and reload webpage on change (like browsersync)

I'm submitting a...


[ ] Regression 
[ ] Bug report
[*] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

It does not seem to be possible with this module.

Expected behavior

There is option to enable livereload. See Browsersync for reference.

What is the motivation / use case for changing the behavior?

It will help a lot.

There is not good way to catch "File not found" errors on static assets

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

So if you setup the ServeStaticModule and provide serveStaticOptions: { fallthrough: false }, the module reports a 500 (Internal Server) error.

I don't know why this is not coming clearly to me, but I want to change the 500 error to a 404, because the file was not found.

I tried to use a global Internal Server filter and match the route in the case of 500 errors, but that wasn't possible because for some reason the filter doesn't get hit. I must be missing something higher level about NestJS.

Expected behavior

I expect there to be an ergonomic way to handle errors when fallthrough is set to false.

Minimal reproduction of the problem with instructions

Use the example in the nest repo: https://github.com/nestjs/nest/blob/master/sample/24-serve-static/src/app.module.ts#L8

and configure your ServeStaticModule to also serve your home directory (just an example) include serveStaticOptions: { fallthrough: false }. Then after you have set up the mount point, start the server and enter a URL under the mount point that would not exist in your home directory. Your browser should report a 500 error.

What is the motivation / use case for changing the behavior?

It currently seems either impossible or not easily discoverable on how a developer can catch the serve-static 500 error and change it to a 404 for when a file is not found.

Environment


Nest version: 7.0.2



Honestly maybe this is an issue for the serve-static repo. I am unsure.

Module '"@nestjs/serve-static"' has no exported member 'ServeStaticModule'.

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

'''
2 import { ServeStaticModule } from '@nestjs/serve-static';

'''

src/app.module.ts:2:10 - error TS2305: Module '"@nestjs/serve-static"' has no exported member 'ServeStaticModule

https://i.imgur.com/YP4gMrS.png

It seems that the static module have a problem.

Minimum reproduction code

https://gist.github.com/bussiere/c1ed49fdb9edb9eda64eebb5b9052878

Steps to reproduce

npm install @nestjs/serve-static

and use
'''
import { ServeStaticModule } from '@nestjs/serve-static';
'''

Expected behavior

that ServeStaticModule can be imported.

Package version

github:nestjs/serve-static

NestJS version

8.2.2

Node.js version

v17.5.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Transform/Manipulate index html before sending it

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

Expose a function to transform the index.html before sending it to the client to inject some variables or replace certain parts, without setting up a complete view engine setup.

Describe the solution you'd like

It would be great to expose a function transformIndexHtml?: (indexHtml: string)=> string | Promise<string>
With this function any transform can be handled.
Here is the diff file I use to patch-package this feature in our code base:

diff --git a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
index a996aff..e1dd974 100644
--- a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
+++ b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
@@ -5,6 +5,7 @@ export interface ServeStaticModuleOptions {
     renderPath?: string | RegExp;
     serveRoot?: string;
     exclude?: string[];
+    transformIndexHtml?: (indexHtml: string) => string;
     serveStaticOptions?: {
         cacheControl?: boolean;
         dotfiles?: string;
diff --git a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
index 75c9f9b..d447522 100644
--- a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
+++ b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
@@ -29,7 +29,19 @@ let ExpressLoader = class ExpressLoader extends abstract_loader_1.AbstractLoader
                         const stat = fs.statSync(indexFilePath);
                         options.serveStaticOptions.setHeaders(res, indexFilePath, stat);
                     }
-                    res.sendFile(indexFilePath);
+                    if(options.transformIndexHtml != null) {
+                      fs.readFile(indexFilePath, 'utf8', (err, data) => {
+                        if (err) {
+                            next(err);
+                            return;
+                        }
+                        const transformed = options.transformIndexHtml(data);
+                        res.set('Content-Type', 'text/html');
+                        res.send(transformed);
+                      })
+                    } else {
+                     res.sendFile(indexFilePath);
+                    }
                 }
                 else {
                     next();

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

We want to inject a variables into the index.html before sending it to the client. In our case we want to replace the <base href="/"/> with the correct baseUrl in case the application runs on a pathname e.g. http://localhost:3001/app. Additionally we want to set a variable on the window object. We don't want to setup the whole view engine and install something like ejs to do these simple transformations.

serveStaticOptions: { index: false } doesn't work

If I set :
ServeStaticModule.forRoot({
rootPath: path.resolve(__dirname, 'static'),
serveStaticOptions: {
index: false
}
})
I still get error in console:
ENOENT: no such file or directory, stat '/../dist/static/index.html'

"@nestjs/serve-static": "2.2.2",
"@nestjs/common": "7.6.15",
"@nestjs/config": "0.6.3",
"@nestjs/core": "7.6.15",

E2e tests fail with version 2.1.1

I'm submitting a...


[x] Regression 
[ ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When running e2e tests, @nestjs/serve-static uses noop loader.
Consequently, my tests for routing are failing because serve-static returns a 404 error on non-existing routes, instead of serving the index.html of the root folder.

With version 2.1.0, when running e2e tests serve-static was using express loader instead of noop loader. So when requesting http://myserver/non-existing-path serve-static was returning a response 200 with /index.html as content.

The culprit is this commit : db6e86d#diff-b38ccc22d6bb4ce4c12a2c61b89a974b

Expected behavior

Testing the routing of @nestjs/serve-static should be possible.

Minimal reproduction of the problem with instructions

Doing the same with @nestjs/serve-static 2.1.0 will succeed

Environment


Nest version: 7.1.3
 
For Tooling issues:
- Node version: 12.16.2
- Platform:  Linux

Serve different folders for different subdomains

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[ x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I'm currently pointing a few subdomains to the same server. All of the subdomains are using the same backend and I was wondering if I can serve different frontends for each of the subdomains.

I know that it's possible using express-subdomain for express:

const subdomain = require('express-subdomain')

const subRouter = express.Router()
subRouter.use('/', express.static(path.join(__dirname, '/../subfrontend/build')))
subRouter.get('/*', (req, res) => {
  res.sendFile(path.join(__dirname, '/../subfrontend/build/index.html`))
})

app.use(subdomain('sub', subRouter))

Is this currently possible to implement using @nestjs/serve-static?

Expected behavior

Each of the subdomains will be served with different frontend

Environment


Nest version: 7.1.3
 
For Tooling issues:
- Node version: 12.16.2
- Platform:  Linux

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

ServeStaticModule serves non-existing paths

I'm submitting a...

[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When using the @nestjs/serve-static module, the server serves any path and does not return a 404 error even if the requested resource does not exist.

Project folder structure

.
β”œβ”€β”€ client
β”‚   └── index.hml
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ app.module.ts

Input Code

// src\app.module.ts
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

imports: [
  ServeStaticModule.forRoot({ rootPath: join(process.cwd(), 'client') })
],

Testing

Request an existing resource

GET / HTTP/1.1
Host: localhost:3000

Response

HTTP/1.1 200 OK

Request a nonexistent resource

GET /foo HTTP/1.1
Host: localhost:3000

Response

HTTP/1.1 200 OK

Expected behavior

Request a nonexistent resource

GET /foo HTTP/1.1
Host: localhost:3000

Response

HTTP/1.1 404 Not Found

Minimal reproduction of the problem with instructions

  1. nest new testcase
  2. npm install --save @nestjs/serve-static
  3. Import ServeStaticModule.forRoot({ rootPath: join(process.cwd(), 'client') }) in app.module.ts
  4. Create folder testcase/client
  5. Create index file index.html under the testcase/client
  6. npm run start
  7. Make request at curl --location --request GET 'localhost:3000/foo'
  8. Got response HTTP/1.1 200 OK but expected HTTP/1.1 404 Not Found

What is the motivation / use case for changing the behavior?

In general, "serve-static" should follow the usual logic while serving files. If requested resource does not exists, an error is returned. Or in documentation should have a place where described this behavior and provided some instruction for handling that situations.

Environment

Nest version: 7.2.0
 
For Tooling issues:
- Node version: v12.16.3
- Platform: Windows

Others:

After updating static-asset to 3.x, excluded paths fallback to index.html ( instead of returning a 404 )

Did you read the migration guide?

  • I have read the whole migration guide

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Potential Commit/PR that introduced the regression

No response

Versions

2.2.2 -> 3.0.1

Describe the regression

Excluded paths that were not found would return a 404. It now fallbacks to index.html

Minimum reproduction code

This test was successful on 2.x

  it('should return 404 for static assets (eg .js, .svg, ...,  which were not found', async () => {
    return request(app.getHttpServer()).get('/app-bad-name.js').expect(404);
  });

Here is the configuration we use :

 imports: [
            ServeStaticModule.forRoot({
          // note: this isn't trying to be an exhaustive list of possible assets
          // we just want to handle the most common ones
          exclude: ['/*.(js|css|eot|ttf|woff|gif|ico|png|svg|jpg)'],
          rootPath,
          serveStaticOptions: {
            maxAge: MAX_AGE_7_DAYS,
            setHeaders: (res, path) => {
              if (path.endsWith('index.html')) {
                 // use .setHeader 
              }
            }
          }

The application fall backs to index.html when a stati

Expected behavior

Excluded path should return a 404

Other

I see that you use path-to-regexp 0.3.5 in your package... it's a bit weird because on our side, when i was building against next@8, I ended up with path-to-regexp 3.x, and when I was building against next@9, I endep up with path-to-regexp 6.x. So something might be wrong on my side too

Provides a small layer on top of serve-static, which allows to serve pre-gzipped files

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Simple serve-static

Expected behavior

Provides a small layer on top of serve-static, which allows to serve pre-gzipped files. Supports brotli and allows configuring any other compression you can think of as well.

Minimal reproduction of the problem with instructions

see https://github.com/tkoenig89/express-static-gzip

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z

 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

renderPath option doesn't work

I'm submitting a...


[ ] Regression 
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

If StaticServer imported with "renderPath" option it doesn't serve assets on /static

Expected behavior

StaticServer should provide all the assets on /static

Minimal reproduction of the problem with instructions

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, 'public'),
      renderPath: "/static" 
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Suggestions for fixing it

I would suggest to edit express.loader.ts file according to Express mount path specification.
Replace

    const clientPath = options.rootPath;
    const indexFilePath = this.getIndexFilePath(clientPath);

    app.use(express.static(clientPath, options.serveStaticOptions));
    app.get(options.renderPath, (req: any, res: any) =>
      res.sendFile(indexFilePath)
    );

with

    const clientPath = options.rootPath;
    app.use(options.renderPath, express.static(clientPath, options.serveStaticOptions));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.