foal

Full-featured Node.js framework 🚀

MIT License

Downloads
33.1K
Stars
1.9K
Committers
64
foal -

Published by LoicPoullain over 5 years ago

Fixes v0.8.0.
[Config] v0.8.0 didn't look at the configuration files in the right order.

foal - February Release

Published by LoicPoullain over 5 years ago

Features

  • [@foal/mongoose] Add support for Mongoose (MongoDB) (issue: #277) (PR: #342).
  • [@foal/cli] Add CLI commands to quickly connect a Vue/React/Angular frontend to the backend (dev & prod) (issue: #279) (PR: #348).
  • Add a type to Context.request (issue: #318) (PR: #337).
  • Automatically parse cookies (issue: #333) (PR: #334).
  • Let the JWT hooks retrieve the token from a cookie (issue: #335) (PR: #336).
  • Let the developer generate a script from anywhere in the project (terminal) (issue: #340) (PR: #349).
  • Simplify the Config system and support YAML (issue: #338) (PR: #351).
  • Remove legacy deprecated components (PR: #353).

How to migrate

npm install -g @foal/cli
npm install @foal/[email protected] # and @foal/[email protected], @foal/[email protected], etc if relevant.

The new configuration system should be the only breaking change in the February release. Feel free to submit an issue if you are having trouble migrating.

  • New versions of Foal uses by default the port 3001 to not conflict with a running React server. You can still keep the port 3000 if you want.

  • Update all the Config.get calls in your code:

// Before
Config.get('mongodb', 'uri');
Config.get('settings', 'staticUrl', 'public/') as string;

// After
Config.get('mongodb.uri');
Config.get<string>('settings.staticUrl', 'public/');
  • Merge all your config files as follows:
Before:
- mongodb.e2e.json
- mongodb.development.json
- settings.development.json
- settings.json

After:
- e2e.json
- development.json
- default.json
// ***********
// Before
// ***********
// mongodb.development.json
{
  "uri": "my_uri"
}
// settings.development.json
{
  "debug": true
}

// ***********
// After
// ***********
// development.json
{
  "mongodb": {
    "uri": "my_uri"
  },
  "settings": {
    "debug": false
  }
}
  • If you're using the @foal/jwt package, replace the env variables JWT_WHATEVER with SETTINGS_JWT_WHATEVER and update your config files as follows:
// incorrect
{
  "jwt": {
    "secret": "xxx"
  },
  "settings": {
    ...
  }
}

// correct
{
  "settings": {
    "jwt": {
      "secret": "xxx"
    },
    ...
  }
}

The settings section now encompasses all the configuration of the official Foal packages.

  • If you customized the AJV instance (validation & sanitization), replace the env variables AJV_WHATEVER with SETTINGS_AJV_WHATEVER and update your config files as follows:
// incorrect
{
  "ajv": {
    "coerceTypes": true
  },
  "settings": {
    ...
  }
}

// correct
{
  "settings": {
    "ajv": {
      "coerceTypes": true
    },
    ...
  }
}

The settings section now encompasses all the configuration of the official Foal packages.

  • Divide the session keys into nested objects:
// Before
{
  "sessionResave": false,
  "sessionSaveUninitialized": false,
  "sessionSecret": "my-secret",
  "sessionCookieHttpOnly": true,
  "sessionCookieMaxAge": 1000,
  "sessionCookieSameSite": "lax",
  "sessionCookieSecure": true,
  "sessionName": "id"
}

// After
{
  "settings": {
    "session": {
      "resave": false,
      "saveUninitialized": false,
      "secret": "my-secret",
      "cookie": {
        "httpOnly": true,
        "maxAge": 3600000,
        "sameSite": "lax",
        "secure": true
      },
      "name": "id"
    }
  }
}

Here's are examples of config files using the new system:

You'll find more information here on how the new configuration system works.

foal -

Published by LoicPoullain over 5 years ago

Features

  • [@foal/cli] Validate params in REST APIs (issue: #344) (PR: #345).
  • Let developers customize the AJV baseline configuration if they want to (issue: #343) (PR: #347).

How to migrate

npm install -g @foal/cli
npm update # in your project
foal -

Published by LoicPoullain over 5 years ago

Features

  • (Bug) Fix type error in JWTOptional and JWTRequired (issue: #328) (#325)
  • Validate project name as per npm conventions (issue: #313) (PR: #326)

Contributors

@LoicPoullain
@jamesgeorge007

foal -

Published by LoicPoullain over 5 years ago

  • [@foal/cli] Make the createapp command not fail when Git is not installed (issue: #319) (PR: #321).
foal - v0.7.3

Published by LoicPoullain almost 6 years ago

Features

  • [@foal/cli] Validate arguments for createapp command (issue: #310) (PR: 309).
  • [@foal/cli] Validates random commands and shows up help if none supplied (issue: #308) (PR: #307).
  • [@foal/cli] Add foal run as alias of foal run-script (PR: #316).
  • [@foal/cli] Make new applications have an architecture example closest to SPA (PR: #315)
  • [@foal/cli] foal createapp: prettify the outputs and auto initialize git repo (issue: #314) (PR #317).

Contributors

@jamesgeorge007
@LoicPoullain

foal -

Published by LoicPoullain almost 6 years ago

Features

  • Add the command foal generate rest-api <name> (PR: #303) (Issues: #278, #288)
  • Be able to customize the logger outputs (PR: #305)
foal - v0.7.0

Published by LoicPoullain almost 6 years ago

How to migrate from v0.6

  • Install the last version of the CLI: npm install -g @foal/cli.
  • Update the dependencies in your package.json:
{
   ...
  "dependencies": {
    "@foal/core": "~0.7.0",
    "@foal/ejs": "~0.7.0",
    "@foal/typeorm": "~0.7.0",
    ...
  }
}
  • Replace parsePassword with encryptPassword(password, { legacy: true })
  • Remove the hook AuthenticateWithSessionAndCookie (you might need to use the LoginOptional hook in some situations)
  • Import fetchUser from @foal/typeorm and replace @LoginRequired() by @LoginRequired({ user: fetchUser(User) )}
  • Rename AbstractUser to UserWithPermissions and import it from @foal/typeorm
  • Import EntityResourceCollection, EmailAuthenticator, emailSchema, middleware, Group, Permission and PermissionRequired from @foal/typeorm instead of @foal/core.

General Notes

The purpose of this release is to make the code of FoalTS less complex, more readable and modular and to add the support of recent technologies (JWT). It introduces some changes and improvements listed below.

The AuthenticationWithSessionAndCookie and LoginRequired hooks have been merged

In previous versions of FoalTS, AuthenticationWithSessionAndCookie and LoginRequired were both required to authenticate and restrict access to authenticated users. They have been merged into one hook LoginRequired for simplicity (and consistency with the JWTRequired hook presented below). A new hook LoginOptional has also been added in this version.

Old code:

import { AuthenticationWithSessionAndCookie, LoginRequired, Get } from '@foal/core';
...

@AuthenticationWithSessionAndCookie(User)
export class AppController {

  @Get('/')
  index(ctx) {
    const name = ctx.user ? ctx.user.name : 'you';
    return new HttpResponseOK(`Hello ${name}!`);
  }

  @Get('/home')
  @LoginRequired({ redirect: '/' })
  home(ctx) {
    return new HttpResponseOK(`Hello ${ctx.user.name}!`);
  }

}

New code:

import { LoginOptional, LoginRequired, Get } from '@foal/core';
import { fetchUser } from '@foal/typeorm';
...

export class AppController {

  @Get('/')
  @LoginOptional({ user: fetchUser(User) })
  index(ctx) {
    const name = ctx.user ? ctx.user.name : 'you';
    return new HttpResponseOK(`Hello ${name}!`);
  }

  @Get('/home')
  @LoginRequired({ redirect: '/', user: fetchUser(User) })
  home(ctx) {
    return new HttpResponseOK(`Hello ${ctx.user.name}!`);
  }

}

Support of JWT with JWTRequired and JWTOptional

This release adds the support of JWT for authentication. The two new hooks JWTRequired and JWTOptional are similar to LoginRequired and LoginOptional.

Example:

import { Get, isInFile } from '@foal/core';
import { JWTRequired } from '@foal/jwt';
import { fetchUser } from '@foal/typeorm';

export class AppController {
  @Get('/home')
  @JWTRequired()
  home(ctx) {
    return new HttpResponseOK(`Hello ${ctx.user.name}!`);
  }
}

export class AppController2 {
  @Get('/home')
  // With some options
  @JWTRequired({ user: fetchUser(User), blackList: isInFile('./blacklist') }, { audience: 'foobar' })
  home(ctx) {
    return new HttpResponseOK(`Hello ${ctx.user.name}!`);
  }
}

Password Management with encryptPassword and verifyPassword

You can now manage password encryption directly with the encryptPassword and verifyPassword functions.

Note: The parsePassword(password) util has been removed. Use its equivalent with encryptPassword: encryptPassword(password, { legacy: true }).

The controller routes are now registered after the sub-controllers routes

In the previous versions of FoalTS, the sub-controllers' routes were registered after the controller routes. Then it was hard to display a custom 404 page when a route did not exist. In the example below, requesting /home was returning a 404 instead of 200 - 'You are on the home page!'

export class ViewController {
  @Get('/')
  index() {
    return new HttpResponseOK('Hello world');
  }

  @Get('/home')
  home() {
    return new HttpResponseOK('You are on the home page!');
  }
}

export class AppController {
  subControllers = [ ViewController ];

  @Get('*')
  notFound() {
    return new HttpResponseNotFound('The page your are looking for does not exist');
  }
}

This is now changed and this example returns a success on GET /home.

TypeORM-dependent components moved in a separate package @foal/typeorm

All TypeORM-dependent components have been moved to a separate package @foal/typeorm.

These components are:

  • EmailUser and EmailAuthenticator (deprecated)
  • emailSchema (deprecated)
  • Middleware, RelationLoader, middleware, EntityResourceCollection (deprecated)
  • Group, Permission, UserWithPermissions
  • PermissionRequired
  • fetchUserWithPermissions, fetchUser

This way developers can use another ORM/ODM if they want (Mongoose, Sequelize, etc)

The User class and the UserWithPermissions entity (previously named AbstractUser)

The abstract class AbstractUser has been renamed into UserWithPermissions.

Because not all applications require permissions and groups, and a different ORM can be used instead of TypeORM, the User class no longer needs to extend the class UserWithPermissions.

The type of Context['user'] is now any. You can force this type with a generic parameter: Context<User>.

The deprecated components

Due to their unnecessary complexity, some components have been deprecated and will be removed in further versions:

  • IAuthenticator
  • Strategy, strategy, LoginController
  • IResourceCollection, CollectionParams
  • RestController
  • EmailUser and EmailAuthenticator
  • emailSchema
  • Middleware, RelationLoader, middleware, EntityResourceCollection

Here are some alternatives that you might consider:

  • encryptPassword and verifyPassword
  • foal generate rest-api <name> (coming in a next release in January 2019)

Features

  • Fix the error ctx.request.csrfToken is not a function when the CSRF protection is disabled (issue: #283) (PR: #284).
  • Add support for JWT (issue: #254) (PR: #272).
  • Merge AuthenticationWithSessionAndCookie and LoginRequired into LoginRequired and LoginOptional(issue: #286) (PR: #287)
  • Provide two util functions encryptPassword and verifyPassword to manage password encryption(issue: https://github.com/FoalTS/foal/issues/288) (PR: #300).
  • Register the controller routes after its sub-controllers (issue #289) (PR: #292).
  • Move EmailAuthenticator, EmailSchema, LoginController, PermissionRequired, AbstractUser, Group, Permission, fetchUser, fetchUserWithPermissions, EntityResourceCollection to the new package @foal/typeorm (issue: #290) (PR: #293 ).
  • Rename AbstractUser to UserWithPermissions and simplify the definition of Context (issue: https://github.com/FoalTS/foal/issues/291) (PR: #293)
  • Mark as deprecated EmailUser, EmailAuthenticator, emailSchema, Middleware, RelationLoader, middleware, EntityResourceCollection, IAuthenticator, Strategy, strategy, LoginController, IResourceCollection, CollectionParams and RestController (issue: #288) (PR: #293, #295).
  • [Docs] Add API reference for each package.
  • Ignore WebStorm and VSCode config directories in Git (https://github.com/FoalTS/foal/pull/297).
  • Change the output directory name (lib/ -> build/) (issue: #296) (PR: #301)

Contributors

@LoicPoullain
@rustamwin

foal - v0.6.2

Published by LoicPoullain almost 6 years ago

foal - v0.6.1

Published by LoicPoullain almost 6 years ago

Features

foal - v0.6.0

Published by LoicPoullain almost 6 years ago

Features

Breaking changes

  • The returned type of a hook function is now void | HttpResponse | HookPostFunction | Promise <void | HttpResponse | HookPostFunction> and not any anymore.
    This means that if you have a hook defined like @Hook(ctx => ctx.state.foo = 2), you to have update its definition as follows: @Hook(ctx => { ctx.state.foo = 2; })
  • The hook Authenticate is now named AuthenticateWithSessionAndCookie.

Contributors

@LoicPoullain
@Jrfidellis

foal - v0.6.0-beta.6

Published by LoicPoullain about 6 years ago

Features

Breaking changes

  • The property headers of HttpResponse is now private. You need to use the setHeader, getHeader and getHeaders methods instead.
  • The optional parameter of the Log Hook is not the log function anymore but an options object.
    @Log('hello', console.error) // before
    @Log('hello', { logFn: console.error }) // after
    
foal - v0.6.0-beta.5

Published by LoicPoullain about 6 years ago

General Note

This release introduces numerous breaking changes. They are the fruit of several feedbacks and should be the last breaking changes of this version. v0.6.0 will come out soon!

Features

Contributors

@LoicPoullain
@Jrfidellis

How to migrate

Update you dependencies

  • Update your local dependencies: npm update.
  • Update globally @foal/cli: npm -g update @foal/cli.

Bug https://github.com/FoalTS/foal/issues/187

Create a new file src/test.ts with the content process.env.NODE_ENV = 'test';. Then in your package.json make the commands start:test and start:test:w start with mocha --file \"./lib/test.js\".

Support e2e tests and improve builds

Simplify shell scripts

Update your scripts following this pattern:

const argSchema = {
  /* ... */
};

export function main(argv) {
  const args = getCommandLineArguments(argv);	
  try {	
    validate(argSchema, args);	
  } catch (error) {	
    if (error instanceof ValidationError) {	
      error.content.forEach(err => {	
        console.log(`The command line arguments ${err.message}`);	
      });	
      return;	
    }	
    throw error;	
  }	
  /* ... */
}

// Replace this with:

export const schema = {
  /* ... */
};

export function main(args) {
  /* ... */
}

ValidateQuery & ValidateBody

The hooks ValidateQuery and ValidateBody now use under the hood this configuration of Ajv:

{
  coerceTypes: true,  // change data type of data to match type keyword
  removeAdditional: true, // remove additional properties
  useDefaults: true, // replace missing properties and items with the values from corresponding default keyword
}

Dependency Injection

  • Remove all the occurrences of the decorators Module, Controller and Service.
  • Follow this pattern in your controllers and services:
@Controller()
export class MyController {
  constructor(private myService1: MyService1, public myService2: MyService2) {}
}
// becomes:
export class MyController {
  @dependency
  private myService1: MyService1;

  @dependency
  myService2: MyService2;
}
  • Change your RestControllers following this pattern:
export class MyController extends RestController {
  collectionClass = MyCollectionClass;
}
// becomes:
export class MyController extends RestController {
  @dependency
  collection: MyCollectionClass;
}
  • If you need to instantiate controllers or services in your tests, use createService or createController.

Modules -> Controllers and SubControllers

  • Rename all your files **.module.ts into **.controller.ts
  • Change the content of your module files following this pattern:
export AppModule implements IModule {
  controllers = [
    controller('/foo', Controller1)
  ];

  subModules = [
     subModule('/api', ApiModule)
  ];
}
// Replace this with:
export AppController {
  subControllers = [
    controller('/foo', Controller1),
    controller('/api', ApiController)
  ];
}
  • Rename the directories sub-modules to sub-apps.
  • In src/index.ts, import AppController instead of AppModule as it no longer exists.
foal - v0.6.0-beta.4

Published by LoicPoullain about 6 years ago

Features

How to migrate

Update you dependencies

Update your local dependencies: npm update.
Update globally @foal/cli: npm -g update @foal/cli.

Database migrations

The entity Group now has a codeName.

  • If you have synchronize set to true in your ormconfig.json then the database schema will automatically be updated.
  • Otherwise run the following commands to update the db schema:
npm run build
npm run migration:generate -- -n add-codename-to-group
npm run build
npm run migration:run

Shell scripts

Remove src/scripts/create-users.ts and add the following scripts:

Session configuration

Remove the line "sessionCookieDomain": "localhost" in config/settings.production.json.

foal - v0.6.0-beta.3

Published by LoicPoullain about 6 years ago

Features

How to migrate

Update your dependencies by running npm update.

The render util

// Before
import { readFileSync } from 'fs';
import { join } from 'path';

const login = readFileSync(join(__dirname, './templates/login.html'), 'utf8');
render(login, { csrfToken: ctx.request.csrfToken() });

// After
render('./templates/login.html', { csrfToken: ctx.request.csrfToken() }, __dirname);

The migrations

  • Move you root migrations directory (if it exists) to src.
  • Update your tslint.json and ormconfig.json with:
{
   ...
   "linterOptions": {
      "exclude": "src/migrations/*.ts"
   }
}
{
   ...
   "migrations": ["lib/migrations/*.js"],
   "cli": {
      "migrationsDir": "src/migrations"
   },
}
foal - v0.6.0-beta.2

Published by LoicPoullain about 6 years ago

  • Make the copy command work on Windows (hot fix).
foal - v0.6.0-beta.1

Published by LoicPoullain about 6 years ago

Features

Steps

  • Remove InitDB and add a createConnection in the main index.ts file instead.
  • Update the build, run and test commands to use copy and to get rid of webpack.
  • Update tsconfig.json and ormconfig.json to use the correct paths.
  • Move the scripts/ directory into src.
  • Replace all the require('**/*.html') by fs reads.

How to migrate

  • Delete your lib/ directory.
  • Update your dependencies by running npm update.
  • The hook InitDB does not longer exist and you don't need to register your entities anymore. Remove the hook from your code and replace the content of src/index.ts by this:
// The imports ...
async function main() {
  await createConnection();

  const app = createApp(AppModule, {
    store: session => new (sqliteStoreFactory(session))({ db: 'db.sqlite3' })
  });

  const httpServer = http.createServer(app);
  const port = Config.get('settings', 'port', 3000);
  httpServer.listen(port, () => {
    console.log(`Listening on port ${port}...`);
  });
}

main();
  • Change the commands of your package.json by this:
{
    "build": "tsc && copy-cli \"src/**/*.html\" lib",
    "build:w": "tsc -w",
    "start": "node ./lib/index.js",
    "start:w": "supervisor -w ./lib --no-restart-on error ./lib/index.js",
    "develop": "npm run build && concurrently \"npm run build:w\" \"npm run start:w\"",

    "build:test": "tsc && copy-cli \"src/**/*.html\" lib",
    "build:test:w": "tsc -w",
    "start:test": "mocha \"./lib/**/*.spec.js\"",
    "start:test:w": "mocha -w \"./lib/**/*.spec.js\"",
    "test": "npm run build:test && concurrently \"npm run build:test:w\" \"npm run start:test:w\"",

    "lint": "tslint -c tslint.json -p tsconfig.json",
    "migration:generate": "ts-node ./node_modules/.bin/typeorm migration:generate",
    "migration:run": "ts-node ./node_modules/.bin/typeorm migration:run",
    "migration:revert": "ts-node ./node_modules/.bin/typeorm migration:revert"
}
  • Update the following properties in your tsconfig.json and ormconfig.json:
// tsconfig
"outDir": "lib" 
//ormconfig
 "entities": ["lib/app/**/*.entity.js"],
  • Move your scripts/ directory to src.
  • Replace all your require('./foobar.html') to fs.readFileSync(path.join(__dirname, './foobar.html'), 'utf8').
foal - v0.6.0-beta.0

Published by LoicPoullain about 6 years ago

Goal: Create complex REST API.

foal - v0.6.0-alpha.4

Published by LoicPoullain about 6 years ago

Goal: having an authentication and authorization system that work.

foal - v0.6.0-alpha.3

Published by LoicPoullain about 6 years ago

Package Rankings
Top 1.86% on Npmjs.org
Top 8.17% on Proxy.golang.org
Badges
Extracted from project README
backers
Related Projects