Elegant and all-inclusive Node.Js web framework based on TypeScript. :rocket:.

Overview


https://foalts.org

License: MIT node version npm version Build Status Code coverage Known Vulnerabilities Commit activity Last commit 2FA 2FA

What is Foal?

Foal (or FoalTS) is a Node.JS framework for creating web applications.

It provides a set of ready-to-use components so you don't have to reinvent the wheel every time. In one single place, you have a complete environment to build web applications. This includes a CLI, testing tools, frontend utilities, scripts, advanced authentication, ORM, deployment environments, GraphQL and Swagger API, AWS utilities, and more. You no longer need to get lost on npm searching for packages and making them work together. All is provided.

But while offering all these features, the framework remains simple. Complexity and unnecessary abstractions are put aside to provide the most intuitive and expressive syntax. We believe that concise and elegant code is the best way to develop an application and maintain it in the future. It also allows you to spend more time coding rather than trying to understand how the framework works.

Finally, the framework is entirely written in TypeScript. The language brings you optional static type-checking along with the latest ECMAScript features. This allows you to detect most silly errors during compilation and improve the quality of your code. It also offers you autocompletion and a well documented API.

Screenshot

Development Policy

For contributors only.

Thousands of Tests

Testing FoalTS is put on a very high priority. Providing a reliable product is really important to us. As of December 2020, the framework is covered by more than 2100 tests.

Documentation

New features, no matter what they offer, are useless if they are not well documented. Maintaining complete and quality documentation is key to the framework. If you think something is missing or unclear, feel free to open an issue on Github!

Product Stability

Great attention is paid to the stability of the product. You can find out more by consulting our dependency policy, semantic versioning rules and long-term support policy.

🌇 Get started

First install Node.Js and npm.

Create a new app

$ npm install -g @foal/cli
$ foal createapp my-app
$ cd my-app
$ npm run develop

The development server is started! Go to http://localhost:3001 and find our welcoming page!

👉 Continue with the tutorial 🌱

Backers & Sponsors

backers

Community Chat

You can join the community chat here.

Contributing

See the contribution guidelines.

License

MIT

Comments
  • Version 2.0 (June-August)

    Version 2.0 (June-August)

    Version 2

    Updated on June 19, 2020.

    This issue provides an overview of the next version of Foal TS. It will be released between June and August 2020.

    The purpose of this release is not to add many new features, which are regularly added in minor versions, but to fix issues and hacks that require some break changes. It will also remove unused and deprecated components and make parts of the framework simpler and more intuitive.

    Changes & New Features

    :white_check_mark: = Implemented

    1. Developper experience (CLI) :white_check_mark:

    Migrations and shell scripts are not developper friendly when developping (#494). There are too many CLI commands and it is not intuitive to know which one to use and in which order.

    In version 2, the files tsconfig.migrations.json and tsconfig.scripts.json will be removed and the CLI commands will be reduced and simplified.

    More details here: #684.

    Examples

    Build, make and run migrations

    # Version 1
    npm run build:app
    npm run migration:generate -- -n my_migration
    npm run build:migrations
    npm run migration:run
    
    # Version 2
    npm run makemigrations
    npm run migrations
    

    Build migrations, scripts and the app

    # Version 1
    npm run build:app
    npm run build:scripts
    npm run build:migrations
    
    # Version 2
    npm run build
    

    2. Authentication with sessions :white_check_mark:

    Authentication with sessions is complicated and requires a lot of code. Current implementation also prevents the framework from adding new features (#525, #521, #510).

    In version 2, the authentication system with sessions will be greatly simplified.

    See #799.

    3. Schema references in validation hooks :white_check_mark:

    It is not possible to use references (especially OpenAPI references) in validation hooks.

    In version 2, this will be fixed.

    More details here: #552.

    Example

    const productSchema = {
      // ...
    }
    
    @ApiDefineSchema('product', productSchema)
    @ValidateBody({
      $ref: '#/components/schemas/product'
    })
    

    4. Service initialization :white_check_mark:

    Services can be initialized using their boot method. For this to work, we currently need to call ServicesManager.boot() in src/index.ts.

    In version 2, this feature will be enabled by default. No need to call ServicesManager.boot() anymore.

    5. Accessing file metadata during uploading :white_check_mark:

    When uploading a file, we have only access to its content (#673).

    In version 2, we will also have access to its file size, mime type and original file name.

    6. Safer configuration :white_check_mark:

    Current Config.get function has several faults (#496).

    In version 2, it will be replaced with the new Config.get2 added in v1.7.

    // Version 1 
    const port = Config.get<number>('settings.port', 3000);
    const port = Config.get<number>('settings.port');
    
    // Version 2
    const port = Config.get('settings.port', 'number', 3000);
    const port = Config.getOrThrow('settings.port', 'number')
    

    7. Improve the naming of JWT settings :white_check_mark:

    Version 1: settings.jwt.secretOrPublicKey

    Version 2: settings.jwt.secret, settings.jwt.publicKey

    8. Remove support of Mongoose :white_check_mark:

    Mongoose brought many problems in the past while maintaining the framework. It takes time to maintain it and it is also not typed and does not seem to be used by FoalTS users: https://www.npmjs.com/package/@foal/mongoose.

    FoalTS will no longer provide Mongoose tools starting from v2 (i.e. CLI code generation and the fetchUser function). Users will still be able to use it "by hand" if they wish.

    9. Improve the configuration system :white_check_mark:

    See #805, #497.

    10. Simplify the management of custom errors thrown in controllers and hooks :white_check_mark:

    See https://github.com/FoalTS/foal/issues/638#issuecomment-673915802.

    Cleanup :white_check_mark:

    • Remove the outdated and useless security headers.
    • Remove the PermissionDenied and ObjectDoesNotExist which are unused and do not appear in the documentation.
    • Remove the object ValidationError and the function validate which are unused and do not bring value to the framework.
    • Remove the deprecated function createHttpResponseFile and use Disk.createHttpResponseFile instead. Once done, remove the package mime from @foal/core dependencies.
    • Remove the package @foal/formidable and use the @ValidateMultipartFormDataBody hook instead.
    • Remove the deprecated legacy option of the functions hashPassword and verifyPassword. This option was used in very old versions of Foal when no one was using the framework.
    • Remove the deprecated package @foal/ejs and the possibility to create FoalTS template engines. Only Express templates engines will be allowed (Twig, EJS, pug, etc).
    • Drop the support of Node 8 and run tests on Node 12 and 14. Version 8 of Node is not maintained anymore. Uninstall pump in @foal/core, @foal/storage and @foal/aws-s3 and use the pipeline function from the standard library (added in Node 10).
    • Remove the unused command foal g sub-app.
    • Check if password hashing needs an update (OWASP).
    • Make createApp return a promise and remove createAndInitApp. The function createAndInitApp was introduced because we needed to return a promise.
      // Before
      const app = createApp();
      const app = await createAndInitApp();
      
      // After
      const app = await createApp();
      
    • Only allow one way to pass a custom express instance to createApp.
      // Before
      const expressInstance = express();
      const app = createApp(expressInstance);
      // OR
      const app = createApp({ expressInstance });
      
      // After
      const expressInstance = express();
      const app = createApp({ expressInstance });
      

    Upgrading Dependencies

    help wanted good first issue 
    opened by LoicPoullain 25
  • Blog articles and Youtube videos

    Blog articles and Youtube videos

    This issue lists potential subjects for the blog and the YouTube channel.

    Feel free to add a 👍 on those you’re interested in. This will help prioritize which content should be written first.

    If you would like to discuss on a subject or suggest a new one, please use the #blog-and-videos channel on Discord. The blog focuses on providing articles on these topics: real-life projects, deployments, tips & tricks and release posts.

    docs / blog / website 
    opened by LoicPoullain 23
  • Translating FoalTS docs to Bahasa Indonesia

    Translating FoalTS docs to Bahasa Indonesia

    FoalTS documentation is awesome. It helps me building a good grasp of how a framework takes care of auth, orm, cli, etc. step by step thru Tutorials and Topic Guides.

    If it's possible, I'd love to translate it — to Bahasa Indonesia. Hope v2 is a good starting point.

    What do you think?

    help wanted docs / blog / website 
    opened by anonimusprogramus 17
  • FoalTS V2: UseSessions - Generates session when requesting static files e.g. favicon.ico

    FoalTS V2: UseSessions - Generates session when requesting static files e.g. favicon.ico

    Been trying to migrate my project from V1 to V2, have found that the new UseSessions generates a session when I'm requesting a static asset, not sure if I'm using it wrongly.

    My front-end controller is as follows:-

    @UseSessions({ store: MongoDBStore, cookie: true })
    export class DefaultController {
        public subControllers = [
            // Checkout - uses cookies
            controller("/checkout", CheckoutController),
        ]
    
        @Get("/*")
        public async defaultView(ctx: Context) {
           // Serves a single page application - using JWT and no cookies
            return new HttpResponseRedirect("/admin");
        }
    
    
    }
    
    question 
    opened by crossinghoods 15
  • Hiding properties from JSON

    Hiding properties from JSON

    The problem

    @Entity()
    export class User extends BaseEntity {
      @PrimaryGeneratedColumn()
      id: number;
    
      @Column()
      name: string;
    
      @Column({ unique: true })
      email: string;
    
      @Column()
      password: string;
    
      @Column({ nullable: true })
      accessToken?: string;
    
      // tslint:disable-next-line:variable-name
      private _client?: ThridPartyClient;
    
      get thridPartyClient(): ThridPartyClient | undefined {
        if (!this._client && this.accessToken) {
          this._client = createThridPartyClient({accessToken: this.accessToken});
        }
    
        return this._client;
      }
    }
    

    Currently, when we return an instance of the above entity (or anything that contains it) from an API endpoint the entire model gets serialized into something like:

    {
      "id": 1,
      "name": "Orkhan",
      "email": "[email protected]",
      "password": "password-hash",
      "accessToken": "blah213",
      "_client": {...}
    }
    

    The last 3 fields must not be inside json. We can of course create a new object and return it but there should be a better solution in general. Does foalts have something to offer in this case?

    Workaround

    We can override toJSON method in the User entity class which is used by JSON.stringify method:

    function hidden(hidden: string[]) {
      return function (this: object) {
        const result = {};
        for (const x in this) {
          if (!hidden.includes(x)) {
            result[x] = this[x];
          }
        }
        return result;
      };
    }
    
    @Entity()
    export class User extends BaseEntity {
     ...
      toJSON = hidden(['password', 'accessToken', '_client']);
    }
    

    Where we call hidden method with the array of field names to hide and it will return a method that returns a new copy of object by not copying specified fields. This works for arrays and nested objects too.

    Proposed solution

    Again I put forward laravel's approach as an example. FoalTS can use a custom replacer to serialize json response, where we can hook in and conditionally hide fields based on some sort of a reserved field on the provided entity (like foal: { hidden: ['password'] }). This would work for arrays and nested objects too.

    feature request 
    opened by OrkhanAlikhanov 14
  • Prettify the

    Prettify the "500 error page" in development

    Currently the 500 error page in development is quite ugly. It would be nice to have something prettier (with a bit of CSS...)

    Capture d’écran 2019-07-17 à 15 17 33

    If someone wants to take care of this, feel free to add a comment below and submit a PR!

    Note: In order to keep the @foal/core package small, the page cannot rely on a 3rd CSS framework (such as Bootstrap for example)

    enhancement help wanted good first issue 
    opened by LoicPoullain 14
  • [Sessions] Support MongoDB as session storage

    [Sessions] Support MongoDB as session storage

    Issue

    We currently have TypeORMStore and RedisStore to store sessions in SQL and Redis databases. It is annoying for people using MongoDB with FoalTS. We should also support MongoDB session storage.

    feature request 
    opened by LoicPoullain 14
  • Be able to customize the global exception handler

    Be able to customize the global exception handler

    This issue was previously named Have hooks to catch rejected promises or uncaught errors. See the latest comments to see the current state of the issue.

    Issue

    In some situations, we want to catch errors thrown or promises rejected in a hook or a controller method. For example, during development, we may want to display a custom 500 page which prettifies the error stack.

    Possible solution

    A possible solution could be to add a CatcherPostHook decorator which would take a CatcherHookPostFunction as parameter. The behavior would be analog to how errors, promises and express middlewares work.

    Empty example

    @CatcherPostHook((err, ctx, services, response) => {
    
    })
    

    Behavior demo

    @Hook(() => {
      console.log(1);
      throw new Error('a');
    })
    @Hook(() => {
      console.log(2);
    })
    @CatcherPostHook((err, ctx, services, response) => {
      console.log(err.message);
      throw new Error('b');
    })
    @Hook(() => {
      console.log(3);
    })
    @CatcherPostHook((err, ctx, services, response) => {
      console.log(err.message);
    })
    @Hook(() => {
      console.log(4);
    })
    
    // Output:
    // 1
    // a
    // b
    // 4
    
    feature request 
    opened by LoicPoullain 14
  • Looking for feedback!

    Looking for feedback!

    Hey guys,

    I'm looking for feedback on Foal and I really want to know what you think! 👍 Also if you do not plan to use the framework in the future, feel free to tell why!

    1. What features do you use? What features are you really excited about?
    2. Are there features that you find useless, complicated or that you do not plan to use?
    3. Did you encounter difficulties when using / learning the framework?
    4. Do you think something is missing?
    5. How do you authenticate your users (session, cookie, jwt, etc)? Do you use Foal components for that?
    6. Do you use sessions?
    7. What do you use Foal for (SPA, REST API, etc) ?

    If you enjoy the framework, feel free to leave a ⭐️on the repository to spread the word! 😄You can also retweet my Looking for feedback tweet!

    help wanted discussion 
    opened by LoicPoullain 12
  • Encoding problems when running the `cli` tests on Windows

    Encoding problems when running the `cli` tests on Windows

    Issue

    Issue reported in the PR https://github.com/FoalTS/foal/pull/206. When running the tests of the cli package on Windows, they all seem to fail because of a line break encoding (\n vs \r\n).

    Possible solutions

    • Ask collaborators to use a virtual machine (for example vagrant) when developing for the project.

    OR

    • Update test-environment.ts to replace all \r\n characters by \n when loading a generated file during tests (maybe easier).
    internal 
    opened by LoicPoullain 12
  • Websocket error in @foal/socket.io/lib/socketio-controller.service

    Websocket error in @foal/socket.io/lib/socketio-controller.service

    Version of FoalTS: 2.8.0

    I tried updating my backend but I am still failing at this error:

    /node_modules/@foal/socket.io/lib/socketio-controller.service.js:59
                         return cb({
                                    ^
     TypeError: cb is not a function
         at Socket.<anonymous> (/node_modules/@foal/socket.io/lib/socketio-controller.service.js:59:28)
         at processTicksAndRejections (node:internal/process/task_queues:94:5)
     Program node ./build/index.js exited with code 1
    

    What can be my problem, did I missed some step in upgrading the project to 2.8?

    Thanks

    bug 
    opened by pospile 10
  • Error with FOAL CONNECT for angular>13 (project) : foal connect angular frontend_dir

    Error with FOAL CONNECT for angular>13 (project) : foal connect angular frontend_dir

    Version of FoalTS: 3.1.0

    First of all : FoalTS is really great!

    I faced the following error when I try to connect an angular frontend project to FOAL, I've got the following error:

    config.projects[config.defaultProject].architect ||= {};
    TypeError: Cannot read properties of undefined (reading 'architect')
    

    If I understand well config.defaultProject has been removed from Angular.json since Angular v14. (found on angular-cli : defaultProject deprecated [https://github.com/angular/angular-cli/issues/23470])

    I found a solution which works for me (on IONIC projects), but not sure that's the best way to solve the issue:

    In node_modules@foal\cli\lib\generate\generators\angular\connect-angular.js :

        if (config.defaultProject === undefined) {
            console.log("NO default project (Angular>14 - use firstproject 'app'?) => ",angularProject);
        }
        config.projects[angularProject].architect ||= {};
        config.projects[angularProject].architect.serve ||= {};
        config.projects[angularProject].architect.serve.options ||= {};
        config.projects[angularProject].architect.serve.options.proxyConfig = 'src/proxy.conf.json';
        // Output build directory
        const outputPath = (0, path_1.join)((0, path_1.relative)(path, process.cwd()), 'public')
            // Make projects generated on Windows build on Unix.
            .replace(/\\/g, '/');
        config.projects[angularProject].architect.build ||= {};
        config.projects[angularProject].architect.build.options ||= {};
        config.projects[angularProject].architect.build.options.outputPath = outputPath;
        return JSON.stringify(config, null, 2);
    

    Hope this could help.

    bug help wanted good first issue 
    opened by Gfoulon 1
  • Generate upload/download pre-signed urls with the Disk util

    Generate upload/download pre-signed urls with the Disk util

    We don't always want to server to handle file uploads, and it's easy enough to use the AWS SDK, but the Disk util is just too convenient. Would it be possible to add this feature to it?

    Something like:

     const { downloadUrl } = await this.disk.createPresignedDownloadUrl('docs/xxx.pdf', 'buffer', {
                  expiresIn: 3600
              });
    
     const { uploadUrl } = await this.disk.createPresignedUploadUrl('docs', content, {
                  expiresIn: 3600
              });
    

    Thought this does present a problem, to how to handle local file upload/downloads in this case, I don't have good idea for that one.

    feature request 
    opened by k0rn4l 2
  • Feature/MongoDB Session Functions

    Feature/MongoDB Session Functions

    Issue

    The MongoDB session store service is missing some functions, which we needed in a past project. In that, we were using FoalTS with MongoDB, and we extended those functionalities. This PR is supposed to contribute them back.

    Solution and steps

    • [x] Add getSessionIDsOf function
    • [x] Add getSessionsOf function (a new one which returns all whole session objects for a user)
    • [x] Add getAuthenticatedUserIds function
    • [x] Add destroyAllSessionsOf function

    Checklist

    • [x] Add function docs
    • [x] Add tests
    • [x] Update foal docs Session Tokens ("This feature is only available with the TypeORM store." comments)
    feature 
    opened by SimonGuethler 2
  • Typed config.get based on default.json

    Typed config.get based on default.json

    Hi, I'm opening a new issue as you asked it in #880 I took a deep dive into the Typescript type system and was able to come up with a type (lot of ideas came from the type-challanges) for the Config.get function:

    • based on the default.json the key parameter is typed, it only accepts strings that are defined in the config file in the same format as the Config.get method accept keys (e.g.: 'port', 'setting.debug')
    • based on the default.json the return type is automatically typed, you don't have to provide any type information to the function

    As you might notice, the solution heavily relies on the default.json, if we want to read a value which is missing from that file, typescript will throw an error. In my opinion this is more of a positive outcome than a negative, as it forces to define a default value for every key that the application will try to read, also making the defaultValue parameter obsolete (defaults should be defined in default.json). Another limitation is in a json file we can only have string, boolean, number, array and object types, the type the function returns with can only be these. So if we want to have a more restricted type (e.g. Stripe API has an Interval type which is a subset of string ("weekly" | "daily" | "manual" | "monthly") and we want to use the value straight from the config) we either need to cast the type, be able to specify the return type of the function similar to the current solution, or have some utility to rewrite the type of the config (which I included in the solution). But in my opinion with these limitations we would get a type-safe, easy-to-use Config functionality. I'm really interested in your opinion (and I don't have a clear idea, how to include this in the framework)

    Some screenshots to show how it works: intellisense can show you all the available keys intellisense can show you all the available keys

    typescript error if key doesn't exists, value automatically typed correctly typescript error if key doesn't exists, value automatically typed correctly

    works with deep keys with dot notation, correctly returns with complex object types works with deep keys with dot notation, correctly returns with complex object types

    I tried to add as many comments as possible, as it is not an easy read :). (it also uses some of the newest features of typescript, I used version 4.7.3)

    import { Config } from '@foal/core';
    import Stripe from 'stripe';
    
    import config from 'config/default.json';
    
    type BaseConfigType = typeof config;
    
    /**
     * SetType<T, K, V>: object
     *   T: object type to modify
     *   K: string key to modify, can be in dot notation format to modify deep key
     *   V: type that key to have
     *   modifies T, overrides the key that K refers to to have the type V
     *   if K is not in T, then T is returned
     */
    // first check if K has a dot in it. if yes H should be the part before the first dot R should be the part after
    type SetType<T extends object, K extends string, V> = K extends `${infer H}.${infer R}`
      ? // we create a new object type
        {
          // the keys should be the same as in T, the type should be the same
          // expect for H: if T[H] is an object then recursively call SetType with that object and the rest of K (R)
          [Key in keyof T]: H extends Key ? (T[H] extends object ? SetType<T[H], R, V> : T[H]) : T[Key];
        }
      : // if K doesn't hava a dot in it then we still create a new object type
        {
          // the keys should be the same as in T, the type should be the same, expect for K: it should be V
          [Key in keyof T]: K extends Key ? V : T[Key];
        };
    
    /**
     * SetTypes<T, KV>: object
     *   T: object to modify
     *   KV: array of key-value doubles, keys are strings can be in dot notation format, values can be any type
     *   modifies T, overrides each key in KV to have the corresponding type in KV
     */
    // let's check if KV is an empty array. if not H should be the first item in the array and R should be the rest (could be an empty array as well)
    type SetTypes<T extends object, KV extends [string, unknown][]> = KV extends [
      infer H extends [string, unknown],
      ...infer R extends [string, unknown][],
    ]
      ? // for each H item in the array we update T with the help of the SetType type (H[0] is the key, H[1] is the value)
        // then we recursively call SetTypes with the updated object and the rest of the array (R)
        SetTypes<SetType<T, H[0], H[1]>, R>
      : // if KV is empty just return with T, the input object
        T;
    
    // examples of rewriting types in the config
    export type ConfigType = SetTypes<
      BaseConfigType,
      [
        ['stripe.interval', Stripe.AccountCreateParams.Settings.Payouts.Schedule.Interval],
        ['stripe.weeklyanchor', Stripe.AccountCreateParams.Settings.Payouts.Schedule.WeeklyAnchor],
      ]
    >;
    
    /**
     * WithPrefix<Pre, Key>: string
     *   Pre: string to prefix Key with
     *   Key: string or number
     */
    // first lets check if Pre is never (we use never instead of empty string when we don't want to add any prefix)
    type WithPrefix<Pre extends string, Key extends string | number> = [Pre] extends [never]
      ? // if there is no prefix just convert Key to a string (needed if it is a number)
        `${Key}`
      : // if Pre isn't empty check if Key is a number
      Key extends number
      ? // if Key is a number, instead of dot notation use square brackets (this will handle arrays)
        `${Pre}[${Key}]`
      : // if Key is a string use dot notation
        `${Pre}.${Key}`;
    
    /**
     * ObjectKeyPaths<T, Pre>: string (union)
     *   T: object to generate key paths from
     *   Pre: string to prefix key paths with, we use never instead of empty string to begin with
     *   generates all the possible keys in T, with dot notation to deep keys, all the keys prefixed with Pre
     */
    type ObjectKeyPaths<T extends object, Pre extends string = never> =
      // Pre is always a key in object if used correctly
      // never | A = A that's why we start with never instead of empty string
      // A | A = A so unioning the same keys multiple times won't cause an issue
      | Pre
      // the idea is to create an object where keys are the same as in T, but values(types) are strings: the keys prefixed with Pre
      // when we created the correct object we can create a union of the values with indexing the object with all the possible keys
      // e.g: this works with tuples(arrays) ['a', 'b', 'c'][number] = 'a' | 'b' | 'c'
      | {
          // we use the same keys as in T, except:
          //  if T is an object we only use string and number keys (filtering symbols)
          //  if T is an array we only use number keys (filtering symbols and functions that are on every array like map, forEach etc.)
          //  this can cause that if we create an object based on an array, then we add some non number keys to it those keys wont be in the end result
          //  but for our use case, this can't happen, because we will read types from a json file
          [Key in T extends unknown[] ? keyof T & number : keyof T & (string | number)]: T[Key] extends object
            ? // if the type of the current key is an object, then we should recursively call ObjectKeyPaths with that object
              // adding the current key prefixed with Pre as the new prefix
              ObjectKeyPaths<T[Key], WithPrefix<Pre, Key>>
            : // if the type isn't an object then just prefix key with Pre
              WithPrefix<Pre, Key>;
          // we use the same logic to index the object when we created the keys for the object
        }[T extends unknown[] ? keyof T & number : keyof T & (string | number)];
    
    type ConfigKeys = ObjectKeyPaths<ConfigType>;
    
    /**
     * Get<T, K>: ?
     *   T: object to get the type from
     *   K: key to read, can be in dot notation to read deep key
     *   gets the type of K from T
     */
    // first check if K has a dot in it, if yes then H should be the part before the first dot R should be the rest
    type Get<T extends object, K extends string> = K extends `${infer H}.${infer R}`
      ? // check if H is a key in T and that key refers to an object
        T[H & keyof T] extends object
        ? // if yes recursively go a level deeper with that object and the rest of K (R)
          Get<T[H & keyof T], R>
        : // else K is not a proper key of T so there is no type to get
          never
      : // if K has no dot in it, then it must be at the root level, we return it with that type
        T[K & keyof T];
    
    export const get = <K extends ConfigKeys>(key: K): Get<ConfigType, K> => {
      return Config.getOrThrow(key);
    };
    
    feature request 
    opened by enepeti 9
Releases(v3.1.0)
  • v3.1.0(Nov 28, 2022)

    Features

    • [x] Update the max-age attribute of the Strict-Transport-Security header to "industry standard" (issue: #1146) (PR: #1155)
    • [x] [CLI] Disable ESLint rule @typescript-eslint/no-non-null-assertion in generated projects (PR: #1178)
    • [x] [Bug] Support whitespaces around variable names in .env files (issue: #1182) (PR: #1185)
    • [x] Support custom cookie domain in social auth (issue: #1099) (PR: #1187)
    • [x] [CLI] Add foal upgrade command (issue: #1158) (PR: #1186, #1193)
    • [x] Fix: support custom OpenAPI "example" keyword in AJV validation (issue: #1192) (PR: #1194)

    Dependencies

    https://github.com/FoalTS/foal/pull/1162

    Dependencies

    Contributors

    • @edw1882
    Source code(tar.gz)
    Source code(zip)
  • v3.0.2(Oct 31, 2022)

  • v3.0.1(Oct 30, 2022)

  • v3.0.0(Oct 28, 2022)

    Features

    • [x] Drop support for Node 10 (unmaintained), 12 (not maintained from April 2022) and 14 (not maintained in less that a year). Support versions 16 and 18.
      • #1029
      • #1070
      • #1075
    • [x] Upgrade all 3p dependencies doing major upgrades (graphql, etc). Specify which minimum version of TypeORM is required. Upgrade the peer dependencies.
      • #1028
      • #1030
      • #1033
      • #1035
      • #1036
      • #1041
      • #1056
      • #1148
      • #1079
      • #1081
      • #1082
      • #1154
    • [x] Use latest version of AJV and use its TS integration (maybe related: #988). Check that the option names are still the same. Check potential conflicts with OpenAPI types.
      • #1037
    • [x] Remove the functions escape and escapeProp. Modern frontend frameworks (React, Angular, Vue, etc) take care of this.
      • #1034
    • [x] Improve the interface of the Context class to mainly improve type safety.
      • #1073
    • [x] Correct the bad design on the precedence of environment variables. (issue: #1021)
      • #1128
    • [x] Support optional fields in @ValidateMultipartFormDataBody (issue: #1008)
      • #1048
    • [x] Support TypeORM 0.3.0.
      • #1074
      • #1089
      • #1091
      • #1092
      • #1093
      • #1094
      • #1095
      • #1096
      • #1098
      • #1100
      • #1156
    • [x] Ignore undefined values in configuration (issue: #1071)
      • #1113
    • [x] Simplify generated CLI files.
      • #1077
    • [x] ~Drop foal generate rest-api command.~
      • #1078
      • #1088
    • [x] Make the session and JWT systems a bit simpler.
      • #1107
      • #1108
      • #1119
      • #1133
      • #1134
      • #1135
      • #1145
      • #1147
      • #1152
    • [x] Miscellaneous

    Dependencies

    Source code(tar.gz)
    Source code(zip)
  • v2.11.0(Oct 9, 2022)

  • v2.10.2(Aug 20, 2022)

    Content

    • [x] [Internal] Add getCsrfTokenFromRequest util (PR: #1138)
    • [x] [Internal] Split directories jwt and sessions into jwt|sessions/core and jwt|sessions/http (PR: #1137)
    • [x] [Internal] Add getCsrfTokenFromCookie and shouldVerifyCsrfToken utils (PR: #1140)
    • [x] [Internal] Reorganize utils in jwt/ and sessions/ (PR: #1141)
    Source code(tar.gz)
    Source code(zip)
  • v2.10.1(Aug 17, 2022)

    Fixes

    • [x] Do not throw errors on uploads with empty filenames (PR: #1129)
    • [x] Add default Content-Type header in Disk.createHttpResponse responses (PR: #1130)
    Source code(tar.gz)
    Source code(zip)
  • v2.10.0(Aug 11, 2022)

    Features

    • [x] @foal/cli included as dev dependency in new projects generated by createapp (issue: #1097) (PR: #1109)
    • [x] [CLI] Do not use http module in new projects (PR: #1118)
    • [x] [CLI] Fix concurrently issue on some OS (issues: #1115, #1022) (PR: #1123)
    • [x] [Internal] [CLI] Add fs.getProjectDependencies and fs.getProjectDevDependencies (PR: #1111)
    • [x] [Internal] Re-organize common/ internal directory (PR: #1122)

    Contributors

    @scho-to

    Source code(tar.gz)
    Source code(zip)
  • v2.9.0(May 29, 2022)

  • v2.8.2(Apr 11, 2022)

    • [x] [CLI] Fix installation with yarn on node 10 (PR: #1058)
    • [x] Show security requirements, servers and external doc of sub-controllers in Swagger auto-generated document (issue: #1057) (PR: #1060)
    Source code(tar.gz)
    Source code(zip)
  • v2.8.1(Feb 21, 2022)

  • v2.8.0(Feb 13, 2022)

    Features

    • [x] Add Websocket/Socket.io support (issue: #481) (PR: #901)
    • [x] Allow to pass a custom redis client to the RedisStore (PR: #1032)
    • [x] Allow to pass a custom MongoDB client to the MongDBStore (PR: #1032)
    • [x] Allow to pass a custom TypeORM connection to the TypeORMStore (PR: #1032)
    • [x] Support ServerSideEncryption for AWS S3 (issue: #1013) (PR: #1040)

    Dependencies

    Source code(tar.gz)
    Source code(zip)
  • v2.7.2(Jan 10, 2022)

  • v2.7.1(Dec 12, 2021)

  • v2.7.0(Dec 12, 2021)

    Features

    • [x] foal g hook and foal g entity support sub-directories (issue: #993) (PR: #994)
    • [x] Support signed cookies (issue: #992) (PR: #996)
    • [x] Make HttpResponse generic to type the body property (PR: #978)
    • [x] Allow to use FOAL_ENV (instead of NODE_ENV) to define the environment name (issue: #1004) (PR: #1007)
    • [x] Add a afterPreMiddlewares option to createApp (issue: #980) (PR: #1003)

    Contributors

    @MCluck90 @kingdun3284

    Source code(tar.gz)
    Source code(zip)
  • v2.6.0(Sep 19, 2021)

    Features

    • [x] Support the array value of the AJV coerceTypes option (issue: #961).
    • [x] Support more strict CSP for Swagger page (issue: #969) (PR: #970)
    • [x] [Bug] [CLI] Support empty angular.json for connect cmd (issue: #982) (PR: #990)

    Dependencies

    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(Jun 11, 2021)

    Features

    • [x] [CLI] npm run develop watches config files (issue: #945) (PR:#947)
    • [x] createOpenApiDocument accepts an optional serviceManager (issue: #949) (PR: #950)
    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(May 19, 2021)

    Features

    • [x] Support Ajv $data option (issue: #920) (PR: #923)
    • [x] [CLI] Simplify default create-user script (PR: #927)
    • [x] [Bug] Fix renderError error (issue: #930) (PR: #931)
    • [x] Add cache option to Disk.createHttpResponse (issue: #401) (PR: #938)

    Contributors

    @ZakRabe

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Apr 22, 2021)

    Features

    • [x] Support .env.local files for configuration (issue: #877) (PR: #899)
    • [x] Support GraphiQL (issue: #439) (PR: #906).
    • [x] Allow to access the service manager in fetchUser and add Prisma docs (issue: #856) (PR: #909).
    • [x] Add streamToBuffer and convertBase64urlToBase64 functions (PR: #910)
    • [x] [Social] Fix state bad URL characters (issue: #754) (PR: #911)

    Dependencies

    Contributors

    • @ognjenjevremovic
    Source code(tar.gz)
    Source code(zip)
  • v1.12.2(Apr 22, 2021)

  • v2.2.0(Feb 25, 2021)

    Features

    • [x] [CLI] Prettify createapp and add spinner (PR: #875)
    • [x] [CLI] Support sub-paths in generate rest-api (issue: #862) (PR: #878)
    • [x] Know if the user is authenticated on the client side when using cookies (issue: #843) (PR: #886).
    • [x] Prettify server output (PR: #885)

    Dependencies

    Source code(tar.gz)
    Source code(zip)
  • v2.1.2(Feb 3, 2021)

  • v2.1.1(Feb 3, 2021)

    Features

    Apologies for adding a new feature here (this does not strictly follow version semantic rules), but it was needed in order to fix a bug.

    • [x] Support better-sqlite3 (issue: #870) (PR: #872)

    Bug fixes

    • [x] The 500 debug page has no scrollbar anymore.
    • [x] Generating new projects with sqlite3 pkg was causing some errors depending on the version of python installed on the host. This kind of errors already happened in the past. To fix this, new projects use better-sqlite3 under the hood. The framework behavior (migrations, permissions, etc) is identical as if sqlite3 library were used. (PR: #872)
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Feb 3, 2021)

    Features

    • [x] Pretiffy the welcome and the "500 error" pages (PR: #833)
    • [x] CLI exits with code 1 when a command fails (PR: #848)
    • [x] Hide unhelpful sqlite3 warnings when using createapp with npm (issue: #667) (PR: #854)
    • [x] Add @All decorator to customize 404 errors when a route has no handler (issue: #750) (PR: #857)
    • [x] Add CSRF option in UseSessions to override the configuration (issue: #859) (PR: #867)

    Dependencies

    Source code(tar.gz)
    Source code(zip)
  • v1.12.1(Dec 3, 2020)

  • v2.0.0(Nov 27, 2020)

    How to upgrade to v2.0

    https://github.com/FoalTS/foal/blob/v2-0-0/docs/upgrade-to-v2/index.md OR (if dead link) https://github.com/FoalTS/foal/blob/master/docs/upgrade-to-v2/index.md

    Features

    General issue: #658

    1. Developper experience (CLI) :white_check_mark:

    • Simplify commands for scripts and migrations (issue: #494) (PR: #684).

    2. Authentication with sessions :white_check_mark:

    Summary: #799.

    • Simplify logout (issue: #726) (PR: #659)
    • Remove the need for a secret (issue: #727) (PR: #742)
    • Do not let TypeORMStore auto-update the database schema (issue: #766) (PR: #767)
    • Allow to query all sessions of a user (issue: #510) (PR: #780)
    • Allow to query all connected users (issue: #778) (PR: #780)
    • Allow to force the disconnection of a user (issue: #779) (PR: #780)
    • Support flash sessions (issue: #521) (PR: #781)
    • Allow to regenerate the session ID for security reasons (issue: #728) (PR: #792).
    • Make it easier to implement a custom session store and maintain it (issue: #794) (PR: #792).
    • Cleanup regularly expired sessions in MongoStore and TypeORMStore (issue: #793) (PR: #792).
    • Make it easier to use templates and to authenticate anonymous users (issue: #795) (PR: #792).
    • [MongoStore] Use sessionID instead of _id to prevent errors on hex vs base64 (issue: #797) (PR: #800)
    • [V2][Sessions] Remove the need of setSessionCookie in login (issue: #796) (PR: #801)
    • Make it easy/fast to use CSRF tokens with sessions (SPA & regular apps) (issue: #798) (PR: #802)
    • Do not save sessions if an error is thrown in a controller or a hook (PR: #823).

    3. Schema references in validation hooks :white_check_mark:

    • Allow to use OpenAPI schema references (issue: #552) (PR: #734)

    4. Service initialization :white_check_mark:

    • Initialize services by default (PR: #733)

    5. Accessing file metadata during uploading :white_check_mark:

    • [File upload] Access file size, mime type, encoding and original file name (issue: #673) (PR: #730)

    6. Safer configuration :white_check_mark:

    • Replace Config.get with Config.get2 (issue: #496) (PR: #732)

    7. Improve the naming of JWT settings :white_check_mark:

    • PR: #802

    8. Remove support of Mongoose :white_check_mark:

    • Remove support of Mongoose (PR: #741)

    9. Improve the configuration system :white_check_mark:

    • Use new configuration system (issues: #497, #805) (PR: #806)

    10. Simplify the management of custom errors thrown in controllers and hooks :white_check_mark:

    • Simplify the management of custom errors thrown in controllers and hooks (issue: #638) (PR: #807)

    11. Cleanup :white_check_mark:

    • Drop NodeJS 8 support and test NodeJS 12 (PR: #699).
    • Remove outdated and useless security headers.
    • Remove the objects ObjectDoesNotExist, PermissionDenied (PR: #718)
    • PR: #804

    Dependencies

    Packages

    Generated projects (foal createapp)

    Source code(tar.gz)
    Source code(zip)
  • v1.12.0(Nov 26, 2020)

  • v1.11.2(Nov 11, 2020)

  • v1.11.1(Aug 13, 2020)

    Features and fixes

    • [x] Fix timeouts in CI which cause some tests to fail.
    • [x] Fix the "overriding" class bug in @ValidateBody (typestack) (issue: #785) (PR: #786)

    Contributors

    @AleksandrSl

    Source code(tar.gz)
    Source code(zip)
  • v1.11.0(Jul 17, 2020)

    Features

    Key features

    • [x] [Sessions] Allow to specify the store name in the configuration (issue: #725) (PR: #729, #759) Doc: https://github.com/FoalTS/foal/blob/master/docs/authentication-and-access-control/session-tokens.md#specify-the-name-of-the-session-store-in-the-configuration
    • [x] Support abstract services (issue: #758) (PR: #759). Doc: https://github.com/FoalTS/foal/blob/master/docs/architecture/services-and-dependency-injection.md#abstract-services
    • [x] Extend ValidateBody from TypeStack to access the controller properties (issue: #752) (PR: #755). Doc: https://github.com/FoalTS/foal/blob/master/docs/validation-and-sanitization.md#usage-with-a-hook

    Small things

    • [x] Remove some useless npm and yarn warnings on install (issue: #695) (PR: #761)
    • [x] [CLI] Catch rejected promises in shell scripts (issue: #671) (PR: #762)

    Contributors

    @AleksandrSl

    Dependencies

    Source code(tar.gz)
    Source code(zip)
Owner
FoalTS
Elegant and all-inclusive Node.Js web framework based on TypeScript.
FoalTS
Fast and type-safe full stack framework, for TypeScript

Fast and type-safe full stack framework, for TypeScript Why frourio ? Even if you write both the frontend and backend in TypeScript, you can't statica

frourio 1.1k Dec 26, 2022
Full stack CQRS, DDD, Event Sourcing framework for Node.js

reSolve is a full stack functional JavaScript framework. CQRS - independent Command and Query sides. DDD Aggregate support. Event sourcing - using eve

ReImagined 709 Dec 27, 2022
A Programming Environment for TypeScript & Node.js built on top of VS Code

Programming Environment for TypeScript & Node.js A battery-included TypeScript framework built on top of Visual Studio Code Website Kretes is a progra

Kretes 677 Dec 11, 2022
🦄 0-legacy, tiny & fast web framework as a replacement of Express

tinyhttp ⚡ Tiny web framework as a replacement of Express ?? tinyhttp now has a Deno port (work in progress) tinyhttp is a modern Express-like web fra

v 1 r t l 2.4k Jan 3, 2023
Noderlang - Erlang node in Node.js

Noderlang allows Node.js programs to easily operate in BEAM environments

devsnek 2 Mar 31, 2022
DDD/Clean Architecture inspired boilerplate for Node web APIs

Node API boilerplate An opinionated boilerplate for Node web APIs focused on separation of concerns and scalability. Features Multilayer folder struct

Talysson de Oliveira Cassiano 3k Dec 30, 2022
💻 Simple and flexible CLI Tool for your daily JIRA activity (supported on all OSes)

jirax ⭐ If you are using this tool or you like it, Star on GitHub — it helps! A CLI tool for JIRA for day to day usage with JIRA.Speed up your JIRA ac

জুনিপ 56 Oct 4, 2022
Modern framework for fast, powerful React apps

FUSION.JS Modern framework for fast, powerful React apps What is it? fu·sion — noun The process or result of joining two or more things together to fo

Fusion.js 1.5k Dec 30, 2022
Clock and task scheduler for node.js applications, providing extensive control of time and callback scheduling in prod and test code

#zeit A node.js clock and scheduler, intended to take place of the global V8 object for manipulation of time and task scheduling which would be handle

David Denton 12 Dec 21, 2021
The most powerful headless CMS for Node.js — built with GraphQL and React

A scalable platform and CMS to build Node.js applications. schema => ({ GraphQL, AdminUI }) Keystone Next is a preview of the next major release of Ke

KeystoneJS 7.3k Jan 4, 2023
:desktop_computer: Simple and powerful server for Node.js

server.js for Node.js Powerful server for Node.js that just works so you can focus on your awesome project: // Include it and extract some methods for

Francisco Presencia 3.5k Dec 31, 2022
Micro type-safe wrapper for Node.js AMQP library and RabbitMQ management.

Micro type-safe wrapper for AMQP library and RabbitMQ management Description Section in progress. Getting Started Qupi can be installed by Yarn or NPM

Grzegorz Lenczuk 2 Oct 5, 2021
🚀 A RESTful API generator for Node.js

A RESTful API generator rest-hapi is a hapi plugin that generates RESTful API endpoints based on mongoose schemas. It provides a powerful combination

Justin Headley 1.2k Dec 31, 2022
nact ⇒ node.js + actors ⇒ your services have never been so µ

nact ⇒ node.js + actors your services have never been so µ Any and all feedback, comments and suggestions are welcome. Please open an issue if you fin

Natalie Cuthbert 1k Dec 28, 2022
In-memory filesystem with Node's API

In-memory filesystem with Node's API

Vadim Dalecky 1.4k Jan 4, 2023
A simple boilerplate generator for your node express backend project! 🚀

A simple boilerplate generator for your node express backend project! ??

Gunvant Sarpate 35 Sep 26, 2022
A nodejs module for local and remote Inter Process Communication with full support for Linux, Mac and Windows

A nodejs module for local and remote Inter Process Communication with full support for Linux, Mac and Windows

Rifa Achrinza 15 Sep 28, 2022
Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks

Actionhero The reusable, scalable, and quick node.js API server for stateless and stateful applications NPM | Web Site | Latest Docs | GitHub | Slack

Actionhero 2.3k Dec 29, 2022