Giter Club home page Giter Club logo

drash's People

Contributors

attebury avatar crookse avatar drashbot avatar dxu23 avatar ebebbington avatar ecrooks-csco avatar eliassjogreen avatar github-actions[bot] avatar guergeiro avatar juzi5201314 avatar mvemcjsunpe avatar player-4 avatar routmoute avatar sant123 avatar saragee3 avatar stelage avatar t8 avatar tweenietomatoes avatar zekth 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  avatar  avatar  avatar  avatar

drash's Issues

Docs: deno_mysql

Summary

What: Documentation for using deno_mysql

Why:

Acceptance Criteria

  • Add acceptance criteria as bulleted list

Example Pseudo Code (for implementation)

// Add example pseudo code for implementation

automate docs deploy

Summary

What: Automate docs deployment when tag is pushed.

Why: Running the deploy script locally to deploy the docs to production can be automated and improve the workflow. Travis CI should deploy the docs when a new tag is pushed.

drashland/http

Summary

What: Split Drash.Http into its own repository. Import code from new repository.

Why: deno-drash should contain a compilation of modules that are imported from other repositories.

Acceptance Criteria

  • create drashland/http
  • put http members in drashland/http
  • import members from drashland/http
  • tests should pass without change

Need document for connect database

Do you have any plan for document to connect the database such as mongodb, mysql etc .. ?
I try some lib of deno to connect mysql such as deno_mysql but i dont know how to use in resource. Like we can pass the client as argument of class resource ?

code beautification

  • make sure example code blocks are work - check tutorials and getting started directories (/docs/src/example_code); follow tutorials to make sure they're still valid
  • consolidate vue templates - some templates don't use page-tutorial-default component and they need to
  • code coverage - all areas of the code base should be tested

Pages

  • Introduction
  • Tutorials
    • Introduction
    • Resources
      • Creating A Resource
      • Content Negotiation
    • Servers
      • Creating A Server
      • Serving Static Paths
    • Responses
      • Adding Content Types
    • Middleware
      • Introduction
      • Adding Server-Level Middleware
      • Adding Resource-Level Middleware
    • Logging
      • Logging To The Terminal
      • Logging To Files
      • Logging Using Log From deno_std
    • Misc
      • Adding Global Members
      • Adding Third-Party Modules
  • Advanced Tutorials
    • Creating A Web App
      • Hello World
        • Part 1 of 4: Handling GET Requests
        • Part 2 of 4: Build The Front-End
        • Part 3 of 4: Handling POST Requests
        • Part 4 of 4: Logging

Drash.Http.Response should not be read-only

Describe the bug
When trying to override Drash.Http.Response, a "read-only" error is thrown.

To Reproduce
Steps to reproduce the behavior:

Run the example app and uncomment line 6.

Expected behavior
Users should be able to overwrite Drash.Http.Response.

Suggested Solution(s)
Use let instead of const in mod.ts.

Namespace for Loggers

Summary

What: Drash should have a Loggers namespace where all loggers can be stored for global use.

Why: Importing the Drash namespace in each file instead of having multiple import lines cleans up the file and creates one way to grab the loggers.

Acceptance Criteria

  • A logger object should be accessible via Drash.Loggers.MyCoolLogger.info("Hello!");
  • A logger object can be added to the Drash.Loggers namespace. This requires renaming the current Drash.Loggers namespace.
  • Names of logger objects in the Drash.Loggers namespace must be unique. An error should be thrown if a logger is added with a duplicate name.
  • Tests
    • Tests will need to be written for the addLogger functionality.
    • Tests will need to be updated when the current Drash.Loggers namespace is renamed.
  • Documentation
    • Update all pages under the Tutorials > Logging section.
    • Update the Tutorials (Creating An App) > Hello World > Part 4 of 4: Logging page
    • If you rename the src/loggers directory, then the directory list in docs/docs.ts will need to be updated. There is a compileApiReferencePageData() function that generates the API Reference page's JSON--using a directory list (a list of directories that it reads through) to find data and store it as JSON.

Example Pseudo Code (for implementation)

// File: mod.ts

Drash {
  ...
  Loggers: {},
  ...
  addLogger(name: string, logger: any) {
    this.Loggers[name] = logger;
  }
}
// File: app.ts (where the logger object is defined and added to Drash.Loggers)

import Drash from "https://deno.land/x/drash/mod.ts";

let myLogger = new Drash.Loggers.FileLogger({
  enabled: true,
  level: "debug"
});

Drash.addLogger("MyLogger", myLogger);
// File: some_file.ts (where the logger object is used--just by importing Drash and referencing Drash.Loggers.MyLogger)

import Drash from "https://deno.land/x/drash/mod.ts";

// Access the MyLogger in the Loggers namespace and write an info log message
Drash.Loggers.MyLogger.info("test");

Request URL needs more parsing

Brief Summary

Request URLs are being parsed with the assumption that they always have a query string. This is wrong. Improve the hydration of HTTP request objects in the Drash.Services.HttpService class so that the request has the following properties:

  • url_query_string
  • url_query_params
  • url_path

Acceptance Criteria

If the URL is localhost:8000/what/the?ok=then, then following properties will return as follows:

  • url_query_string: ok=then WITHOUT the question mark.
  • url_query_params: {ok: "then"}
  • url_path: /what/the (include the leading slash)

If the URL is localhost:8000/what/the, then following properties will return as follows:

  • url_query_string: null
  • url_query_params: {}
  • url_path: /what/the (include the leading slash)

If the URL is localhost:8000, then following properties will return as follows:

  • url_query_string: null
  • url_query_params: {}
  • url_path: /

HTTP Resource Lifecycle Hooks

Brief Summary

Resource classes should have the following lifecycle hooks:

hook_beforeRequest()
hook_afterRequest()

Acceptance Critera

  • The hook_beforeRequest() method should be performed before any request method is called.
  • The hook_afterRequest() method should be performed after any request method is called. This hook should be performed before the response is sent to the client.

Example Code

// File: users_resource.ts

import Drash from "https://deno.land/x/drash/mod.ts";
import AuthService from "/path/to/my/auth_service.ts";
import UserService from "/path/to/my/user_service.ts";

/**
 * Export the resource that handles user data.
 */
export default class UsersResource extends Drash.Http.Resource {
  /**
   * Define this resource's paths
   */
  static paths = ["/users"];

  /**
   * Handle GET requests
   */
  public GET() {
    try {
      this.response.body = UserService.getUsers();
    } catch (error) {
      this.response.body = "Woops. We couldn't get the list of users for you."
    }
    return this.response;
  }

  /**
   * Handle DELETE requests
   */
  public DELETE() {
    let userId = this.request.body.user_id;
    try {
      UserService.delete(userId);
      this.response.body = "User deleted.";
    } catch (error) {
      this.response.body = "Fail.";
    }

    return this.response;
  }

  /**
   * Perform the following lifecycle hook before any request is made.
   */
  protected hook_beforeRequest() {
    if (this.request.method == "DELETE" && !AuthService.currentUser().is("admin")) {
      throw new Drash.Exceptions.HttpException(401);
    }
  }
}

Use deno_std/media_types

Summary

What: Use the media types standard module instead of mime-db.

Why: I didn't know deno had its own media types handler. It uses mime-db. It doesn't make sense to manage mime-db in Drash when it's already managed by deno's standard modules.

Acceptance Criteria

  • remove mime_db
  • use deno_std/media_types
  • update docs
  • tests

Release 1.0

Release Date: May 13, 2020
Code freeze: May 1, 2020

  • E2E test app_test.ts
    • This will need to implement multiple resources that cover most (if not all) the entire Drash Lifecycle
  • Update the Drash Lifecycle Diagram
  • #173 Use the Accept header
    • Implementation
    • Documentation
  • #175 import { Drash } instead of import Drash
    • Implementation
    • Documentation
  • #183 Support HTTPS
    • Implementation
    • Documentation
  • #186 resource-level middleware decorators
    • Implementation
    • Documentation
  • #200 server-level middleware standardization
    • Implementation
    • Documentation
  • #197 expose Drash.version
    • Implementation
    • Documentation (just rebuild API Reference)
  • #196 expose Drash.Http.Server.port
    • Implementation
    • Documentation (just rebuild API Reference)
  • #199 await server.run()
    • Implementation
    • Documentation

Make Drash portable

Summary

What: CI to compile Drash down to JS for portability

Why: Portability is cool.

Acceptance Criteria

  • add compilation script
  • script runs in CI process
  • script can be used manually

doc block parser is parsing multiline signatures and more (not smart enough)

Describe the bug
When parsing doc blocks for JSON output for the API reference, the doc blocks end up with characters that aren't expected to be matched.

https://regexr.com/ shows that more than what's expected is being matched.

To Reproduce
Steps to reproduce the behavior:

  1. Open up https://regexr.com/.
  2. Copy and paste contents of server.ts into regexr.
  3. Copy re_all_members regex in doc_blocks_to_json.ts and paste it as the expression in regexr.
  4. See how default export class Server { .... is being matched.

There are also multiple instances of this in doc_blocks_to_json.ts.

Expected behavior
None of the bodies of the methods/functions should be matched.

Suggested Solution(s)
Parse single line and multi line members separately, then combine them to be parsed altogether.

DocBlock parser

Summary

What: Need a DocBlock parser to generate API Reference page(s).

Why: After some investigating, TypeDoc seems to be the best option for generating docs. However, without editing its internals, you can't really parse .ts files (especially Deno-friendly .ts files). Errors are thrown because of linting, errors are thrown because TypeDoc can't find imports, etc. Just make a parser for now until something better and faster comes along.

Acceptance Critera

  • Parser must output parsed docblocks into JSON. Sample below (it doesn't have to meet the sample's exact spec):

    {
        "my_cool_class.ts": {
            "properties": [
                {
                    "name": "property_one",
                    "type" "string"
                },
                {
                    "name": "property_two",
                    "type" "boolean"
                }
            ],
            "methods": [
                {
                    "name": "MethodOne",
                    "params": [],
                    "returns": [
                        {
                            "type": "void",
                            "description": "It just delegates."
                        }
                    ],
                    "throws": []
                },
                {
                    "name": "MethodTwo",
                    "params": [
                        {
                            "type": "any",
                            "name": "object",
                            "description": "The object to use."
                        },
                        {
                            "type": "key",
                            "name": "key",
                            "description": "The key to find in the object to use."
                        }
                    ],
                    "returns": [
                        {
                            "type": "any",
                            "description": "Returns the value of the key in the object to use."
                        }
                    ],
                    "throws": []
                }
            ]
        }
    }
  • Unit tests are required.

Example Pseudo Code (for implementation)

let files = {
  "file.js": {}
}

for (let key in files) {
  files[key] = parseDocBlocks(key);
}

parseDocBlocks(file: string) {
    // do something
}

parseDocBlock(docBlock: string) {
    // do something
}

Tagged Logging

Users should be able to add tags to log messages. Examples below:

INFO | some tag | some tag | some tag | The log message.
  • The logger classes should take in a tag_string config that defines how the tags are arranged.
  • The logger classes should take in a tag_string_fns config that defines each tag.
  • The format of a tag in the tag_string config is {some_tag} (with the brackets so they can be replaced easily).
  • The {level} tag is a reserved tag. Specifying a level key in the tag_string_fns config does nothing.

Example code

The following app ...

// File: app.ts

import Drash from "https://deno.land/x/drash/mod.ts";

let logger = new Drash.Loggers.ConsoleLogger({
  enabled: true,
  level: "all",
  tag_string: "[ {datetime} ] {machine_hostname} | {level} ({hello}) |",
  tag_string_fns: {
    datetime: function() {
        return (new Date()).toISOString();
    },
    hello: "World",
    machine_hostname: "E15"
  }
});

logger.info("The application has started");

... passed to the deno command ...

#!/bin/bash

deno app.ts --allow-write

... should output the following:

[ 2019-03-10T14:22:15.728Z ] E15 | INFO (World) | The application has started.

make codebase portable

Summary

What: Code should be portable so that it can be used with other runtimes/frameworks/etc. (e.g., Node)

Acceptance Criteria

  • All runtime environment specific code (e.g., Deno.env()) should be exported from a single file. Said file will serve as the entry point for code belonging to the system using Drash.
    • Filename should be: system.ts

Template Engine

Summary

What: Drash.Compilers.TemplateEngine

Why: Template engines are essential to building server-rendered web apps in Drash. Currently, the only template engine that works really well in Deno is dejs. However, it's a third-party module and it's up to the user to implement it. It would be nice for a template engine to already be available in Drash if the user wants to use it.

Acceptance Criteria

Example Pseudo Code (for implementation)

See https://krasimirtsonev.com/blog/article/Javascript-template-engine-in-just-20-line instructions

Prism.js laggy when highlighting big blocks of code

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to /api-reference/compilers and you'll see the main thread is blocked
  2. Done.

Expected behavior
Pages with big blocks of code should not have Prism.js block the main thread. Blocking the main thread causes the page to appear frozen. You can see why this is bad.

Possible Solution(s)

  • Recompile Prism.js with minimal code/plugins.
  • Use webworker?

Screenshots
NA

Abstract the Logic that Gets View Contents

Summary

What: Abstract the logic that reads a view file and decodes it into a serpate method that takes a view name.

Why: Simplifies the code the user has to write, resulting i less boilerplate the user has to add. Will result in a single line of code the user has to write, instead of creating a decoder and writing that logic themselves

Acceptance Criteria

  • Logic required to return a view file is handled within a new custom method Drash implements

  • User should be able to get a views contents with: `this.response.render('/users/add.html', { data })

  • Update Documentation

Example Pseudo Code (for implementation)

** Server constructor would need to check if there's a views_path if views_renderer exists **

constructor(...) {
  if (configs.views_renderer && !configs.views_path) {
    throw an error
  }
}

** Server configs would need updating:**

interface ServerConfigs {
  ...
  views_path?: string,
  views_renderer?: any

The views path and renderer would need to be passed in to the instantiation of the response class in Drash.Http.Server.handleHttpRequest() and anywhere else a response object is created in the server object

// server.ts
new Drash.Http.Response(request, {
  views_renderer: this.configs.views_renderer,
  views_path: this.configs.views_path
});

Response class would need to add some extra configuration and a new method

Response {
  constructor(request: any, options: any = {}) {
    this.request = request;
    this.headers = new Headers();
    if (options.views_renderer) {
      this.renderer = options.views_renderer;
      this.views_path = options.views_path; // if there's a views renderer, then there must be a views_path
    };
    this.headers.set("Content-Type", request.response_content_type);
  }
  public render(...args) {
    args[0] = this.views_path += args[1];
    return this.renderer(...args);
  }
}

Example Pseudo Code (for user)

// app.ts
import { render } from "dejs/mod.ts"; // if the user wants to use dejs

class MyResource extends Drash.Http.Resource {
  public GET() {
    // Get dejs view with dynamic data
    this.response.body = this.response.render("users/add.ejs", {my: "data", goes: "here"});
    // get dejs view with no dynamic data
    this.response.body = this.response.render("/users/add.dejs")
    // get html view with no dynamic data
    this.response.body = this.response.render("/users/add.html")
    // get html view with dynamic data
    this.response.body = this.response.render("/users/add.html", {my: "data", goes: "here"})
    return this.response;
  }
}

const server = ({
  ...
  views_path: "path/to/views", // can be omitted if not rendering views
  views_renderer: render// can be omitted if not rendering views
})

move documentation to new repo

Summary

What: Move documentation to new repo

Why: /docs is growing and the Drash module needs to be lean. It's dumb to have to download the documentation to use the Drash module.

Acceptance Criteria

  • /docs is removed
  • documentation works in new repo

types for all members

Summary

What: All members in the Drash namespace should have a type associations.

Why: Stricter syntax, more explosions when bad code is introduced, better API Reference page output.

This work requires deno-drash-docs to be recompiled. See deno-drash-docs' Workflows for committing changes to deno-drash-docs.

Acceptance Criteria

  • all members have types where possible
  • tests pass (console/tests)
  • deno-drash-docs API Reference page recompiled to reflect added types
    • update deno-drash version in package.json to reflect tag used for this work
    • make pull request to staging branch; verify work https://drash.land/staging

Middleware

Pull Request

#97

Summary

What: Add support for middleware.

Why: Most frameworks come with middleware support. Drash should also support this. This will remove the resource lifecycle hooks, but will clean up the process. For example, middleware will help unify resources that would share the same lifecycle hook logic.

Acceptance Criteria

  • Tests
  • Documentation
    • Intro
    • Server-level
    • Resource-level
    • Locations
  • Resources can define their own middleware.
  • The server can define middleware that is processed for every request. It'd be annoying to have to define shared middleware in each resource.
  • Middleware can be set to run at certain points of the request-resource-response lifecycle.
  • Add git hook instructions

Example Pseudo Code (for implementation)

// Resource

import Drash from "https://deno.land/x/drash/mod.ts";
import MiddlewareOne from "./middleware/middleware_one.ts";
import MiddlewareTwo from "./middleware/middleware_two.ts";

export default class MyResource extends Drash.Http.Resource {
  static paths = ["/"];

  static middleware = [MiddlewareOne, MiddlewareTwo];

  public GET() {
    this.response.body = "GET request received!";
    return this.response;
  }
}
// Server configuration

import Drash from "https://deno.land/x/drash/mod.ts";
import MiddlewareForAllRequestsOne from "./middleware/middleware_for_all_requests_one.ts";
import MiddlewareForAllRequestsTwo from "./middleware/middleware_for_all_requests_two.ts";
import ResourceOne from "./resources/resource_one.ts";
import ResourceTwo from "./resources/resource_two.ts";

let server = new Drash.Http.Server({
  address: "localhost:1337",
  middleware: [
    MiddlewareForAllRequestsOne,
    MiddlewareForAllRequestsTwo
  ],
  response_output: "application/json",
  resources: [
    ResourceOne,
    ResourceTwo
  ]
});

server.run();

Auto-build routes; stop entering them manually

Summary

What: Importing every route manually in _bundle.js is getting old. This should be automated using watchmedo.

Why: Laziness...

Acceptance Critera

  • When watchmedo starts/restarts the docs server, it should build all of the routes automatically
  • import() should not be used

Example Pseudo Code (for implementation)

None

405 being thrown instead of 500

Describe the bug
When a resource's request method is executing code and that code suddenly throws an error, the Drash server shows a "405 Method Not Allowed" response. Clearly, the method exists, but for some reason the error being thrown in the method is being thrown as a 405.

To Reproduce
Steps to reproduce the behavior:

  1. Create the following resource (assumes you've created the server to handle the resource):
// file: app.ts
import Drash from "https://deno.land/x/drash/mod.ts";

class HomeResource extends Drash.Http.Resource {
  static paths = [
    "/"
  ];
  public GET() {
    let contents = JSON.parse(decoder.decode(Deno.readFileSync("./somefile.ext")));
    this.response.body = contents;
    return this.response;
  }
}

let server = new Drash.Http.Server({
  address: "localhost:1337",
  response_output: "application/json",
  resources: [HomeResource],
});

server.run();
  1. Start the server: $ deno --allow-net --allow-read --allow-env app.ts
  2. Navigate to localhost:1337

Expected behavior
A 500 error should be thrown and the error message from the erroneous code should be displayed.

Drash.Http.Server.redirect();

Please view https://github.com/drashland/deno-drash/blob/master/DEV.md before starting.

Summary

What: Handle redirects

Why: Currently, Drash doesn't have any type of redirect feature. Although users can send a response with a redirect status code, it'd be much more convenient if the server handled that for them.

Acceptance Criteria

  • documentation on handling redirects. This should fall under the Misc section.
  • tests
  • server.redirect should redirect to the specified location with the specified status code (see below)

Example Pseudo Code (for implementation)

server.redirect(httpStatusCode: number, location: string) { ... }

Use GitHub Actions

Summary

What: Use GitHub Actions

Why: I think it's better to manage the CI process through GitHub since the code is here.

Acceptance Criteria

  • Remove repo from Travis CI
  • Remove travis.yml
  • Add ci.yml via GitHub Actions
  • Have step in CI that runs console/tests
  • Update master shield to use GitHub Actions

content negotiation doesn't make sense anymore

Summary

What:

In #99, revising of the Content Negotiation docs revealed that the logic to get the Response-Content-Type header from the request happens in the response and doesn't make sense for it to be that way.

Why:

If a resource is responsible for determining its representation based on the request, then it should get that information from the request and not the response. The response already gets this information from the request, so we're just making the getting of that information uniform.

Acceptance Criteria

  • The request should have a response_content_type property.
  • The assignment should happen in Drash.Services.HttpService.

Decorator validation support

Whether the framework lacks a verification layer, and whether to consider supporting such writing methods as decorator pattern in the future

Deno v0.36.0 and v0.37.0 support

Summary

This is probably something already being worked on and i am probably just nagging but deno v0.36.0 and v0.37.0 support would be nice to have. Currently when i tried to upgrade the dependencies failing in the old version it failed at the following test: missing CSRF token and errored at the following test wrong CSRF token (#138). When running the example everything seemed to work fine otherwise.

Cookie handling

Please view https://github.com/drashland/deno-drash/blob/master/DEV.md before starting.

Summary

What: Handle cookies.

Why: Cookies are part of the request-resource-response lifecycle, but the Drash server doesn't handle them yet.

Acceptance Criteria

  • documentation (should be under the Misc section and it should reference https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)
  • tests
  • cookie schema matches schema in MDN
  • use Cookie interface that Deno has defined
  • resources should be able to call this.server.getCookie() and this.server.setCookie().
  • resources should be able to get cookies from the request. the HttpRequestService should be the class that handles parsing cookies; and resources should be able to call this.request.getCookie() or something similar that makes sense
  • resources should be able to set cookies on the response (e.g., this.response.setCookie() or something similar that makes sense)
  • build api_reference.json file and update deno-drash-docs to use it.

Example Pseudo Code (for implementation)

server.setCookie();
server.getCookie();

The methods above should implement https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies as closely as possible

import crookse/drash

Summary

What: Import crookse/drash code

Why: crookse/drash code will contain all of the core and common logic that's used to create the deno-drash microframework. It's written in TS, compiled to JS, and can be used in any JS platform.

Acceptance Critera

  • Remove Dictionaries
  • Remove Exceptions
  • Remove Logger and ConsoleLogger
  • Have FileLogger use imported Drash BaseLogger
  • Remove util logic not dependent on deno_std; have util use imported Drash util

cannot read property of undefined when parsing request path params

Describe the bug

When a resource specifies paths with and without path params and check for those path params regardless if they're present, then the following error could occur:

"Cannot read property '{the_path_param}' of undefined"

To Reproduce
Steps to reproduce the behavior:

Load the following resource in a Drash server and make a GET / request.

import Drash from "https://deno.land/x/drash/mod.ts";

export default class HomeResource extends Drash.Http.Resource {
  static paths = [
    "/",
    "/:something"
  ];

  public GET() {
    this.response.body = "GET request received!";

    let pathParam = this.request.getPathParam("something");
    if (pathParam) {
      this.response.body += ` Path param "${pathParam}" received!`;
    }

    let queryParam = this.request.getQueryParam("something");
    if (queryParam) {
      this.response.body += ` URL query param "${queryParam}" received!`;
    }

    let bodyParam = this.request.getBodyParam("something");
    if (bodyParam) {
      this.response.body += ` Body param "${bodyParam}" received!`;
    }

    let headerParam = this.request.getHeaderParam("Something");
    if (headerParam) {
      this.response.body += ` Header param "${headerParam}" received!`;
    }

    return this.response;
  }
}

Expected Behavior

request.path_params = {} should be the default

Actual Behavior

request.path_params doesn't exist if a resource doesn't specify any path params

Suggested Solution(s)

request.path_params = {} should be the default

`generateHtmlResponse` doesn't support async overrides

Description

In Part 2 of the Tutorial, an override of Drash.Http.Response is introduced with member method of async generateHtmlResponse().

class Response extends Drash.Http.Response {
  public async generateHtmlResponse(): Promise<any> {
    const path = Deno.cwd() + "/src/index.ejs"
    const rawOutput = await renderFile(path, {body: this.body});
    const html = rawOutput.toString();
    return html;
  }
}

Drash.Http.Response = Response;

The problem arises when Drash.Http.Response.send() calls Drash.Http.Response.generateResponse() which invokes the overriden function Response.generateHtmlResponse() without awaiting it:

// deno-drash/http/response.ts
public send(): any {
  let body = this.generateResponse(); // <--- returns a promise, should be awaited
  let output = {
    status: this.status_code,
    headers: this.headers,
    body: new TextEncoder().encode(body) // <-- ERR! trying to encode `Promise {}`
  };

  this.request.respond(output);

  return output;
}

Which causes it to crash:

Deno server started at localhost:1337.

Request received: GET /
Calling HomeResource.GET() method.
Sending response. Content-Type: text/html. Status: 200 (OK).
Error occurred while handling request: GET /
Sending response. Content-Type: text/html. Status: 500 (Internal Server Error).
Uncaught TypeError: input is not iterable
    at stringToCodePoints (js/text_encoding.ts:51:19)
    at encode (js/text_encoding.ts:456:36)
    at send (file:///Users/lwong/Library/Caches/deno/deps/https/raw.githubusercontent.com/crookse/deno-drash/v0.7.8/src/http/response.ts:184:31)
    at handleHttpRequestError (file:///Users/lwong/Library/Caches/deno/deps/https/raw.githubusercontent.com/crookse/deno-drash/v0.7.8/src/http/server.ts:281:21)
    at handleHttpRequest (file:///Users/lwong/Library/Caches/deno/deps/https/raw.githubusercontent.com/crookse/deno-drash/v0.7.8/src/http/server.ts:207:21)
    at run (file:///Users/lwong/Library/Caches/deno/deps/https/raw.githubusercontent.com/crookse/deno-drash/v0.7.8/src/http/server.ts:330:12)

Reproduction steps

Follow the tutorial with the [email protected] and [email protected]

Expected behaviour

Overriding generateHtmlResponse with an async function should work

Package versions

package version
deno 0.3.7
deno-drash 0.7.8
dejs 0.2.0

static_paths default or extend

Summary

provide a default path capability for a bare static_paths request or way to extend the resource
What: Explain ...
if a bare request is done for a configured static path ie '/app' with a default ie 'index.html' it should serve the default ie /app/index.html
Why: Explain ...
serve app with a pretty url http://domain.tld/app

Acceptance Criteria

  • explained above

Example Pseudo Code (for implementation)

at the moment static paths can't be configured like other resources, but it should behave like this and also still serve the other static resources

export class StaticResource extends Drash.Http.Resource {
  static paths = ['/app'];
  public GET() {
    try {
      const raw = Deno.readFileSync(`./app/index.html`);
      this.response.body = new TextDecoder().decode(raw);
      return this.response;
    } catch (error) {
      throw new Drash.Exceptions.HttpException(400, 'index error');
    }
  }
}

Switch Vendor namespace to Members

Summary

What: Currently, the Drash.addMember() function adds a new member to the Drash.Vendor namespace. The namespace should be Drash.Members.

Why: Semantics.

Acceptance Criteria

  • A member should be accessible via Drash.Members.MyMember
  • Members must be unique

Example Pseudo Code (for implementation)

None.

Mock Server Isn't Closing Before The Next One

Describe the bug
A test doesn't seem to close the mock server, so it fails when running the next test as the address is in use, see below for the error:

S D:\Development\environments\deno-drash> deno test --allow-env --allow-net .\tests\unit\http\middleware_test.ts
Compile file:///D:/Development/environments/deno-drash/.deno.test.ts
running 12 tests
middleware.ts
OK     - (0.00ms)

Deno server started at localhost:1557.

OK     server/resource: missing CSRF token (24.00ms)

Deno server started at localhost:1557.

error: Uncaught AddrInUse: Only one usage of each socket address (protocol/network address/port) is normally permitted. (os error 10048)
► $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    at unwrapResponse ($deno$/dispatch_json.ts:40:11)
    at sendSync ($deno$/dispatch_json.ts:67:10)
    at listen ($deno$/net.ts:170:15)
    at serve (server.ts:492:20)
    at run (server.ts:418:24)
    at middleware_test.ts:49:10
    at runTests ($deno$/testing.ts:157:22)

It passes the first test, and fails the second, which helps confirm the server hasn't actually closed yet

To Reproduce
Steps to reproduce the behavior:

  1. Cd into the root directory
  2. Run the following command:
    deno test --allow-env --allow-net .\tests\unit\http\middleware_test.ts
    3.. See error

Expected behavior
Tests should be able to run after one another and the mock server should be closed before running the next text (which is also creating a mock server)

Suggested Solution(s)
Couldn't say, maybe there's a race condition or server.deno_server.close(); isn't working as expected

Desktop (please complete the following information):

  • OS: [Windows 10]
  • Deno:
deno 0.33.0
v8 8.1.108
typescript 3.7.2

Additional context
Disocvered this problem whilst developing the solution to issue #115 types for all members when I tried testing. I tested on a branch without any of my changes and the error still showed

Images aren't being served properly

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Create a mini app with one resource accessible at the / URI with a GET method.
  2. In the GET method, set the response to return an image (any image).
  3. Run the app.
  4. Load the resource in the browser and you'll see that the image doesn't render. In Firefox, you'll see a "it contains errors" message.

Expected behavior
Drash.Http.Server should be able to send images with the correct MIME type and images should show up in the browser if they exist.

Suggested Solution(s)
Check out how the contents of the image are being read in Drash.Http.Response.sendStatic() and see if any special-case encoding/decoding needs to happen.

Screenshots
Screen Shot 2019-03-21 at 4 47 01 PM

Access to request body

Summary

What: Access to this.request.body.

Why: this.request.url_query_params, this.request.path_params, and this.request.body should all be accessible to find HTTP variable values.

Acceptance Critera

  • this.request.body should be accessible in all members that have access to the request object.

Custom error handling

How to catch the exceptions of the framework? I want to handle the exception information myself

test example apps in docs

Summary

What:

Add unit tests for example apps in the docs. The example apps are the code blocks in the the tutorials.

Why:

Currently, the only tests run for the example apps in the docs are manual tests. There's no for sure way to know that the example code works with changes from Deno and changes from Drash unless each app is run manually. Also, it's a maintenance nightmare waiting to happen.

Acceptance Criteria

  • One test suite (a single test file) for each tutorial.
  • Tests pass

server logger not accessible from resource

Describe the bug
The server logger is not accessible from the resource class. For example, calling this.server.logger.debug("some debug message.") in a resource class will throw Property 'logger' is protected and only accessible within class 'Server' and its subclasses.

To Reproduce
Steps to reproduce the behavior:

Run the following app:

import Drash from "https://deno.land/x/drash/mod.ts";

class HomeResource extends Drash.Http.Resource {
  static paths = ["/"];
  public GET() {
    this.server.logger.fatal("This is a FATAL log message.");
    this.server.logger.error("This is an ERROR log message");
    this.server.logger.warn("This is a WARN log message");
    this.server.logger.info("This is an INFO log message");
    this.server.logger.debug("This is a DEBUG log message");
    this.server.logger.trace("This is a TRACE log message");
    this.response.body = "GET request received!";
    return this.response;
  }
}

let server = new Drash.Http.Server({
  address: "localhost:1337",
  response_output: "application/json",
  resources: [HomeResource],
  logger: new Drash.Loggers.ConsoleLogger({
    enabled: true,
    level: "all"
  })
});

server.run();

Expected behavior
this.server.logger should be accessible.

Suggested Solution(s)
Make logger property in Drash.Http.Server public.

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.