diff --git a/types/roads/index.d.ts b/types/roads/index.d.ts new file mode 100644 index 0000000000..55028403b6 --- /dev/null +++ b/types/roads/index.d.ts @@ -0,0 +1,245 @@ +// Type definitions for roads 5.0 +// Project: https://github.com/Dashron/roads +// Definitions by: Francisco Jesus +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.6 +/// + +/** + * Roads module + */ +export type Keys = string; +export type Option = {[k in Keys]: any}; + +/** + * @param method The HTTP method that was provided to the request + * @param url The URL that was provided to the request + * @param body The body that was provided to the request, after it was properly parsed into an object + * @param headers The headers that were provided to the request + * @param next The next step of the handler chain + */ +export interface Router { + method: string; + path: string; + fn: () => void; +} + +/** + * @param babelify A set of options that can influence the build process. See all fields below + * @param envify An object to pass to envify. This allows you to change values between your server and client scripts + * @param exclude An array of files that should not be included in the build process + * @param use_sourcemaps Whether or not the build process should include source maps + */ +export interface Options { + babelify?: Option; + envify?: Option; + exclude?: string[]; + external?: any; + use_sourcemaps?: boolean; +} + +/** + * A Road is a container that holds an array of functions + * @see new Road() + */ +export class Road { + /** + * Add a custom function that will be executed before every request + * @param fn Will be called any time a request is made on the object. + * @see Road.use(Function fn) + */ + use(fn: (method: string, url: any, body: any, headers: Headers, next: () => any) => any): any; + + /** + * Locate and execute the resource method associated with the request parameters + * @param method The request HTTP method + * @param url The request Url + * @param body the request body + * @param headers The request headers + * @see Road.request(string method, string url, dynamic body, Object headers) + */ + request(method: string, url: string, body?: any, headers?: Headers): any; +} + +/** + * The response object contains all of the information you want to send to the client + * @param body The body of the response + * @param status The HTTP Status code + * @param headers Key value pairs of http headers + * @see Road.Response + */ +export class Response { + constructor(body: any, status: number, headers?: Option); + + /** + * Add a cookie method to the response object. Allows you to set cookies + * @param name The name of the cookie + * @param value The value name + * @param options Cookie options + */ + setCookie(name: string, value: string, options?: any): void; + + /** + * Get all the cookies + */ + getCookies(): any; +} + +/** + * A helper error, that contains information relevant to common HTTP errors + * @param message A message describing the HTTP error + * @param code An official http status code + * @see Roads.HttpError + */ +export class HttpError { + invalid_request: number; + unauthorized: number; + forbidden: number; + not_found: number; + method_not_allowed: number; + not_acceptable: number; + conflict: number; + gone: number; + unprocessable_entity: number; + too_many_requests: number; + internal_server_error: number; + constructor(message: string, code: number); +} + +/** + * Middleware object + */ +export namespace middleware { + /** + * Very simple middleware to apply a single value to the request context + * @param key The key that should store the value on the request context + * @param val val The value to apply to the request context + */ + function applyToContext(key: string, val: any): () => any; + + /** + * Middleware to kill the trailing slash on http requests + * @see killSlash() + */ + function killSlash(): any; + + /** + * Middleware to Apply proper cors headers + * @param allow_origins Either * to allow all origins, or an explicit list of valid origins + * @param allow_headers A white list of headers that the client is allowed to send in their requests + */ + function cors(allow_origins: string | string[], allow_headers?: string[]): any; + + /** + * Translate the request body into a usable value + * @param body request body + * @param content_type media type of the body + */ + function parseBody(body: any, content_type: string): object | string; + + /** + * Adds two simple functions to get and set a page title on the request context. This is very helpful for isomorphic js, since on the client, page titles aren't part of the rendered view data. + */ + function setTitle(): any; + + /** + * Applies a method to the request context that allows you to make requests into another roads object + * @param key The name of the key in the request context that will store the roads request + * @param road road The roads object that you will interact with + */ + function reroute(key: string, road: Road): () => any; + + /** + * Middleware to Apply proper cors headers + */ + class SimpleRouter { + /** + * It have all the routers configured + */ + routers: Router[]; + + /** + * @param road The road for the routers + */ + constructor(road?: Road); + + /** + * @param road apply manualy the router middleware + */ + applyMiddleware(road: Road): void; + + /** + * Add a route to receive the request + * @param method Methot to receive the request + * @param path Paht to receive the request + * @param fn Handle the request received + */ + addRoute(method: string, path: string, fn: (url: any, body: any, headers: Headers, next: () => any) => any): any; + + /** + * Receive file request + * @param file_path path of the file to receive + * @param prefix prefix of the path file + */ + addRouteFile(file_path: string, prefix?: string): any; + } +} + +/** + * To integrate to differents HTTP server + */ +export namespace integrations { + /** + * Integration to express + * @param road The Road object that contains all routing information for this integration + */ + function express(road: Road): () => any; + + /** + * Integration to koa + * @param road The Road object that contains all routing information for this integration + */ + function koa(road: Road): () => any; +} + +/** + * A helper object to easily enable PJAX on your website using roads + */ +export class PJAX { + /** + * @param road The road that will turn your pjax requests into HTML + * @param container_element The element that will be filled with your roads output + * @param window The pages window object to help set page title and other items + */ + constructor(road: Road, container_element?: Element | null, window?: Window | null); + + /** + * Adds middleware to the assigned road whcih will adds setTitle to the request context. This allows you to easily update the page title + */ + addTitleMiddleware(): this; + + /** + * Assigns the cookie middlware to the road to properly handle cookies + * @param document The pages document object to properly parse and set cookies + */ + addCookieMiddleware(document: Document): any; + + /** + * Hooks up the PJAX functionality to the information provided via the constructor + */ + register(): any; + + /** + * @param response_object The response from the roads request + */ + render(response_object: object): any; +} + +/** + * Browserify function to convert your script to run in the browser + * @param input_file The source file that will be converted to use in the browser + * @param output_file The output file that will be accessible by your browser + * @param options A set of options that can influence the build process. See all fields below + */ +export function build(input_file: string, output_file: string, options?: Options): any; diff --git a/types/roads/roads-tests.ts b/types/roads/roads-tests.ts new file mode 100644 index 0000000000..6914c3d218 --- /dev/null +++ b/types/roads/roads-tests.ts @@ -0,0 +1,68 @@ +import { build, Road, middleware, integrations, Response, HttpError, PJAX } from "roads"; + +const road = new Road(); +const router = new middleware.SimpleRouter(road); + +road.use(middleware.cors("*")); + +road.use(middleware.killSlash); + +router.addRoute("GET", "/user", (path, body, headers, next) => { + const response = new Response({name: "test"}, 200, {"last-modified": (new Date()).toString()}); + response.setCookie("name", "value", {path: ''}); + response.getCookies(); + return response; +}); + +router.addRouteFile('./example.png', 'http://image-example.com'); + +road.request("GET", "/user") + .then((response: any) => { + console.log(`response: ${JSON.stringify(response)}`); + }); + +road.use((method, url, body, headers, next) => { + return JSON.stringify({ + method, + url, + body, + headers, + next + }); +}); + +road.use((method, url, body, headers, next) => { + // execute the actual resource method, and return the response + return next() + // Catch any errors that are thrown by the resources + .catch ((err: any) => { + // Wrap the errors in response objects. If they are [HttpErrors](#roadshttperror) we adjust the status code + switch (err.code) { + case 404: + return new HttpError(err.massage , 404); + case 405: + return new HttpError(err.massage, 405); + case 500: + default: + return new HttpError(err.massage, 500); + } + }); +}); + +const pjax = new PJAX(road, document.getElementById('container'), window); +pjax.register(); +build(__dirname + '/static/client.js', __dirname + '/static/client.brws.js', { + use_sourcemaps: true, + external: { + roads: { + output_file: __dirname + '/static/roads.brws.js', + }, + react: { + output_file: __dirname + '/static/react.brws.js', + } + }, + babelify: {presets: ['react']} +}); + +const koa = integrations.koa(road); +const express = integrations.express(road); diff --git a/types/roads/tsconfig.json b/types/roads/tsconfig.json new file mode 100644 index 0000000000..ac8a53a641 --- /dev/null +++ b/types/roads/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "roads-tests.ts" + ] +} diff --git a/types/roads/tslint.json b/types/roads/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/roads/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +}