GithubHelp home page GithubHelp logo

iyobo / amala Goto Github PK

View Code? Open in Web Editor NEW
50.0 6.0 8.0 3.8 MB

Lightweight NodeJs library for creating API endpoints with Typescript decorators. Supports API versioning, OpenAPI3 and docker. Powered by Koa 2+, Koa-router and Nigerian food (amala+ewedu)

License: MIT License

TypeScript 99.38% JavaScript 0.62%
koa2 controller rest-api router koa-router openapi3 typescript

amala's People

Contributors

anonrig avatar dependabot[bot] avatar georgyfarniev avatar iyobo avatar kindlyiyobo avatar yurasmetanka avatar zrubenst 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

amala's Issues

Create roadmap

Hi @iyobo, I think we need some roadmap to define project scope and features. The last one is necessary to prevent us from working on same issue simultaneously. I don’t have much time but I want to help with PR’s (if you want). Also I think it’s important to keep this project simple as now, but it need better documentation and existing features support.

The problem of other frameworks such as nestjs is their complexity. Not all projects need all this features, but really most rest API needs features provided by this project, such as input validation and injection of parameters.

I think this module has bright future after some polishing and popularization.

Regards, George

class-validator not support ValidateNested

export default class FileParam {
  @ValidateNested()
  metadata: FileMetadataParam;
}

export class FileMetadataParam {
  @IsPositive()
  public size: number;
}


   // controller
  @Post("")
  async upload(@Body() fileParam: FileParam, @Ctx() ctx: Context) {
      // todo
  }

License

What is the license for the code from this repository?

Donation

Please enable donation to this project, at least via github

Injected arguments that should be null or undefined end up as empty object

Example:

@Controller('/test')
export class TestController {
	@Get('/whoami')
	@Flow(AuthMiddleware(false))
	async getTest(@CurrentUser() user: any): Promise<any> {
		console.log(user); // logs "{}" If ctx.state.user is null/undefined
		return user ?? "unknown"; // returns "{}" instead of "unknown" if ctx.state.user is null/undefined
	}
}

Support OpenAPI spec file generation (JSON)

This controller library gives endpoints all the self-documentation they need to generate OpenAPI spec files.
Let's make that happen.

Ideally, the openAPI spec should be generated and cached during bootstrapControllers(...), the result of which can then be manually used by users as they deem fit.

e.g to serve from an endpoint or to be outputed into a JSON file.

To keep this module simple and flexible, The specifics of how to output/use the spec file should be left to the users.

Support ability to pass in Controller classes directly

Right now, we rely on providing bootstrapControllers a glut to get all controllers per bootstrap.
We should allow for the ability to provide an array of not only glut strings describing where these class files are, but actual Classes as well.

Current project status

Hello. First of all, thanks for creating this package! It's really sad that https://github.com/typestack/routing-controllers/ is almost dead now and I was glad to see your project. I just want to know about your plans for this project and if it's ready to use for serious application.

I want to keep things simple, that's why I want to avoid complicated things such as nest. everything I need is basic routing and decorator-based injections and validations, things that your library provides.

So, what is your plans about it? Will you continue develop it? Will you at least accept PR's?

Thanks 👍

Params type conversion

If I supply @Params('id') id: number, then it should be converted to number. A good example can be found in type-graphql library.

Use API versioning on top level instead of controller decorator

Hi. It would be nice to have option of creating version globally, not by picking specific controllers with @Version() decorator. For example:

await bootstrapControllers(app, {
    router,
    basePath: '/api',
    initBodyParser: true,
    boomifyErrors: true,
    versions:{
        1: './version1_controllers/**/*.ts',
        2: './version2_controllers/**/*.ts'
    }
});

Or just use custom controllers structure, not just list, but object with version prefixes similar to versions...

Consult, constructor has no effect

image

How does the constructor take effect when the bootstrapControllers is initialized?

For example, like this ok
export class App{
constructor(private name:string = "111"){
}
test(){
console.log(this.name)
console.log('test function')
}
}
const app = new App()
app.test()

multer support for amala

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, `${file.fieldname}-${Date.now()}-${file.originalname}`)
  },
})
const upload = multer({ storage: storage })

@Controller('/')
class UploadController {
  @Flow([upload.single('image')])
  @Post('/upload')
  upload(@File() files: Record<string, File>) {
    console.log(files)
  }
}

this is my code that doesn't give any errors at all. I get the file in logs, but I can't upload it.

Without using amala with only koa, everything works fine. I assume that the problem is a different way of processing the request, since it is impossible to access the fields through amala

originalname
fieldname and etc...

Therefore, multer receives incorrect data, I cannot solve the problem in any way.

is there a way to make friends with amala and multer?

Support for uploaded files

I'd love to be able to inject uploaded files through @koa/multer. Just like routing-controllers does.

Would you accept a PR for this? I'd love to send you one.

SyntaxError: Cannot use import statement outside a module

Hi!

First of all congrats on this beautiful project. I didn't want to bother with a bug I've been facing, but here's the truth:

path /Users/yagiz/Workspace/alfred/src/**/*/controller.ts
(node:44681) UnhandledPromiseRejectionWarning: /Users/yagiz/Workspace/alfred/src/admin/account/controller.ts:1

I'm receiving this error on the following code:

  await bootstrapControllers(app, {
    router,
    basePath: '/',
    controllers: [__dirname + '/**/*/controller.ts'],
    initBodyParser: true,
    boomifyErrors: true,
    disableVersioning: true
  })

My .babelrc is:

{
  "presets": [["env", { "modules": false }], "@babel/preset-typescript"],
  "plugins": [
    "@babel/plugin-transform-modules-commonjs",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "@babel/proposal-class-properties",
    "@babel/proposal-object-rest-spread"
  ]
}

And my tsconfig.json is:

{
  "compileOnSave": false,
  "exclude": [
    "node_modules",
    "docs",
    "migrations",
    "seeders",
    "tests",
    "websites",
    "dist"
  ],
  "include": ["./**/*.ts"],
  "compilerOptions": {
    /* Basic Options */
    "incremental": true /* Enable incremental compilation */,
    "target": "ES5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
    "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
    "lib": [
      "ES5",
      "ES2016",
      "ES2017"
    ] /* Specify library files to be included in the compilation. */,
    "allowJs": true /* Allow javascript files to be compiled. */,
    "checkJs": true /* Report errors in .js files. */,
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    "declaration": true /* Generates corresponding '.d.ts' file. */,
    // "declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */,
    "sourceMap": true /* Generates corresponding '.map' file. */,
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./dist" /* Redirect output structure to the directory. */,
    "rootDir": "./" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
    // "composite": true /* Enable project compilation */,
    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
    "removeComments": true /* Do not emit comments to output. */,
    // "noEmit": true /* Do not emit outputs. */,
    "importHelpers": true /* Import emit helpers from 'tslib'. */,
    "downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */,
    // "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,

    /* Strict Type-Checking Options */
    // "strict": true /* Enable all strict type-checking options. */,
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true /* Enable strict null checks. */,
    // "strictFunctionTypes": true /* Enable strict checking of function types. */,
    "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    "noUnusedLocals": true /* Report errors on unused locals. */,
    // "noUnusedParameters": true /* Report errors on unused parameters. */,
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,

    /* Module Resolution Options */
    "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
    "baseUrl": "." /* Base directory to resolve non-absolute module names. */,
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */

    /* Source Map Options */
    "sourceRoot": "." /* Specify the location where debugger should locate TypeScript files instead of source locations. */,
    "mapRoot": "." /* Specify the location where debugger should locate map files instead of generated locations. */,
    // "inlineSourceMap": true /* Emit a single file with source maps instead of having a separate file. */,
    // "inlineSources": true /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */,

    /* Experimental Options */
    "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
    "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  }
}

Race condition on generateEndPoints function

By default we're using lodash each function to iterate over actions of the endpoints and using async function as a callback, to run promises inside this.

When iterating through node inspect mode, I couldn't find any issue but, when running through an actual npm start I've received the following error:

By default lodash each iteraction doesn't wait for callback function async to finish and may cause inconsistencies like the following:

https://github.com/iyobo/koa-ts-controllers/blob/master/src/util/generateRoutes.ts#L94

(node:84929) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 24)
(node:84929) UnhandledPromiseRejectionWarning: TypeError: undefined is not a function
    at /Users/yagiz/Workspace/alfred/node_modules/koa-ts-controllers/dist/util/generateRoutes.js:110:32
    at /Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:4905:15
    at baseForOwn (/Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:2990:24)
    at /Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:4874:18
    at Function.forEach (/Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:9342:14)
    at _generateEndPoints (/Users/yagiz/Workspace/alfred/node_modules/koa-ts-controllers/dist/util/generateRoutes.js:80:22)
    at /Users/yagiz/Workspace/alfred/node_modules/koa-ts-controllers/dist/util/generateRoutes.js:143:19
    at /Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:4905:15
    at baseForOwn (/Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:2990:24)
    at /Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:4874:18
    at Function.forEach (/Users/yagiz/Workspace/alfred/node_modules/lodash/lodash.js:9342:14)
    at Object.generateRoutes (/Users/yagiz/Workspace/alfred/node_modules/koa-ts-controllers/dist/util/generateRoutes.js:140:22)
    at Object.exports.bootstrapControllers (/Users/yagiz/Workspac

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.