Exemple #1
0
        private IReadOnlyList <Endpoint> Update(StaticFileOptionsProvider staticFileOptionsProvider)
        {
            const string HtmlExtension      = ".html";
            const string CatchAllSlugPrefix = "...";

            var staticFileOptions = staticFileOptionsProvider.StaticFileOptions;
            var requestDelegate   = CreateRequestDelegate(this.endpointRouteBuilder, staticFileOptions);
            var endpoints         = new List <Endpoint>();

            foreach (var filePath in TraverseFiles(staticFileOptions.FileProvider))
            {
                if (!filePath.EndsWith(HtmlExtension))
                {
                    continue;
                }

                var fileWithoutHtml = filePath.Substring(0, filePath.Length - HtmlExtension.Length);
                var patternSegments = new List <RoutePatternPathSegment>();
                var segments        = fileWithoutHtml.Split('/');

                // NOTE: Start at 1 because paths here always have a leading slash
                for (int i = 1; i < segments.Length; i++)
                {
                    var segment = segments[i];
                    if (i == segments.Length - 1 && segment == "index")
                    {
                        // Skip `index` segment, match whatever we got so far.
                        // This is so that e.g. file `/a/b/index.html` is served at path `/a/b`, as desired.

                        // TODO: Should we also serve the same file at `/a/b/index`? Note that `/a/b/index.html` will already work
                        // via the UseStaticFiles middleware added by `NextjsStaticHostingExtensions.UseNextjsStaticHosting`.
                        break;
                    }

                    var match = slugRegex.Match(segment);
                    if (match.Success)
                    {
                        string slugName = match.Groups[1].Value;
                        if (slugName.StartsWith(CatchAllSlugPrefix))
                        {
                            // Catch all route -- see: https://nextjs.org/docs/routing/dynamic-routes#catch-all-routes
                            var parameterName = slugName.Substring(CatchAllSlugPrefix.Length);
                            patternSegments.Add(
                                RoutePatternFactory.Segment(
                                    RoutePatternFactory.ParameterPart(parameterName, null, RoutePatternParameterKind.CatchAll)));
                        }
                        else
                        {
                            // Dynamic route -- see: https://nextjs.org/docs/routing/dynamic-routes
                            patternSegments.Add(
                                RoutePatternFactory.Segment(
                                    RoutePatternFactory.ParameterPart(slugName)));
                        }
                    }
                    else
                    {
                        // Literal match
                        patternSegments.Add(
                            RoutePatternFactory.Segment(
                                RoutePatternFactory.LiteralPart(segment)));
                    }
                }
                var endpointBuilder = new RouteEndpointBuilder(requestDelegate, RoutePatternFactory.Pattern(patternSegments), order: DefaultEndpointOrder);

                endpointBuilder.Metadata.Add(new StaticFileEndpointMetadata(filePath));
                endpointBuilder.DisplayName = $"Next.js {filePath}";
                var endpoint = endpointBuilder.Build();
                endpoints.Add(endpoint);
            }

            return(endpoints);
        }
Exemple #2
0
        internal NextjsEndpointDataSource(IEndpointRouteBuilder endpointRouteBuilder, StaticFileOptionsProvider staticFileOptionsProvider)
        {
            this.endpointRouteBuilder = endpointRouteBuilder ?? throw new ArgumentNullException(nameof(endpointRouteBuilder));
            _ = staticFileOptionsProvider ?? throw new ArgumentNullException(nameof(staticFileOptionsProvider));

            this.endpoints = this.Update(staticFileOptionsProvider);
        }