0.0.55 • Published 3 years ago

qoq v0.0.55

Weekly downloads
504
License
MIT
Repository
github
Last release
3 years ago

QOQ

A restful node framework for real type checking, a new way for avoiding syntax mistake and saving life. It's based on popular koa2, almostly the total middlewares can be integrated into here.

🔥 no typescript, no coding.

License GitHub Workflow Status (branch) Codecov npm

Features

  • web router
  • console commander
  • validator
  • caching
  • slot
  • strong type-checking

Installation

yarn add qoq

Official Related

ProjectVersionPlatformDescription
qoq-sequelizenpmWeb, Consoledatabase ORM (mysql, sqlite, ...)
qoq-redisnpmWeb, Consoleredis command, cache extension
qoq-compressnpmWebgzip, brotli
qoq-morgannpmWeblogger
qoq-corsnpmWebCORS
qoq-ratelimitnpmWebrequest rate limiter
qoq-jwtnpmWebvalidating json token
qoq-etagnpmWebheader: etag
qoq-response-timenpmWebheader: X-Response-Time
qoq-helmetnpmWebsecurity headers
qoq-pretty-jsonnpmWebformat JSON
qoq-staticnpmWebstatic file serve
qoq-viewsnpmWebtemplate rendering
qoq-json-errornpmWebJSON error handler

And more from koa community...

Demos

Hello World

Usage

Create web app

// src/index.ts
import { WebApplication } from 'qoq';

const app = new WebApplication();

app.listen(3000, () => {
  console.log('Server started!');
});

Create web slots (middleware)

// src/bootstrap/web.ts
import { WebSlotManager, Tree } from 'qoq';
import { Cors } from 'qoq-cors';
import { Redis } from 'qoq-redis';

export const webSlots = WebslotManager
  .use(new Cors())
  .use(new Redis())
  .use((ctx, next) => {
    console.log(ctx.request.ip);
    return next();
  });
export const advancedSlots = webSlots.use(...).use(...);

// the trunk will always run through
// until slot or router interrput it ( by skip execute next() ).
Tree.trunk(advancedSlots);

Create web router

// src/routers/index.ts
import { WebRouter, validator } from 'qoq';
import { webSlots } from '../bootstrap/web';

export const router = new WebRouter({
  prefix: '/',
  // slots behind webSlots will be convert to router group slots
  slots: webSlots.use(new CustomSlot()).use(...),
});

router
  .get('/user/:id')
  .params({
    id: validator.number,
  })
  .action(async (ctx, payload) => {
    const userId = payload.params.id; // TS type annotation: number
    const user = await ctx.redis.get(`user-${userId}`);

    !user && ctx.throw(400, 'user not found');
    ctx.body = user;
  });

router
  .get('/users')
  .query({
    // page is required, otherwise a 400 bad-request error will be thrown.
    page: validator.number,
    // pageSize is optional and will set to 10 when data is undefined/null.
    pageSize: validator.number.default(10),
  })
  .action(async (ctx, payload) => {
    // TS type annotation: { page: number; pageSize: number }
    const { page, pageSize } = payload.query;
    const users = await User.findAll({
      offset: (page - 1) * pageSize,
      limit: pageSize,
    });

    ctx.body = users;
  });

router
  .post('/user')
  .body({
    name: validator.string,
    vip: validator.boolean.default(false),
    homepage: validator.url.optional(),
  })
  .action(async (ctx, payload) => {
    // TS type annotation of body: { name: string; vip: boolean; homepage?: string }
    const user = await User.create(payload.body);

    ctx.status = 201;
    ctx.body = user;
  });

Create console app

// src/index.ts
import { ConsoleApplication } from 'qoq';

const app = new ConsoleApplication();

app.execute().then(() => {
  // Optional invoke here.
  process.exit(0);
});

Create console router

// src/commands/index.ts
import { ConsoleRouter, validator } from 'qoq';
import { webSlots } from '../bootstrap/web';

export const router = new ConsoleRouter({
  prefix: '/',
  slots: consoleSlots
    // as router group slots
    .use(new CustomSlot()),
});

router
  .command('my:schedule')
  .options({
    dateFrom: validator.string.optional(),
    dateTo: validator.string.optional(),
  })
  .alias({
    f: 'dateFrom',
    t: 'dateTo',
  })
  .action(async (ctx, payload) => {
    // TS type annotation: { dateFrom?: string; dateTo?: string }
    const { dateFrom, dateTo } = payload.options;

    // ...your business
    console.log('Done!');
  });

You can execute this command like this:

npx qoq my:schedule
# or
npx qoq my:schedule --dateFrom '..' --dateTo '..'
# or
npx qoq my:schedule -f '..' -t '..'

For testing, feel free to execute command as follows:

test ('can do something', async () => {
  const app = new ConsoleApplication();
  const ctx = await app.execute('my:schedule', '-f', '..', '-t', '..');
  expect(...);
});

Cli

npx qoq -h
# or
yarn qoq -h
# or
node ./src/console.js -h
# or
ts-node ./src/console.ts -h
0.0.40

3 years ago

0.0.41

3 years ago

0.0.42

3 years ago

0.0.43

3 years ago

0.0.44

3 years ago

0.0.45

3 years ago

0.0.46

3 years ago

0.0.47

3 years ago

0.0.37

3 years ago

0.0.38

3 years ago

0.0.39

3 years ago

0.0.32

3 years ago

0.0.33

3 years ago

0.0.34

3 years ago

0.0.35

3 years ago

0.0.36

3 years ago

0.0.51

3 years ago

0.0.52

3 years ago

0.0.53

3 years ago

0.0.54

3 years ago

0.0.55

3 years ago

0.0.48

3 years ago

0.0.31

3 years ago

0.0.30

3 years ago

0.0.26

3 years ago

0.0.27

3 years ago

0.0.28

3 years ago

0.0.29

3 years ago

0.0.25

3 years ago

0.0.23

3 years ago

0.0.24

3 years ago

0.0.22

3 years ago

0.0.21

3 years ago

0.0.20

3 years ago

0.0.19

3 years ago

0.0.17

3 years ago

0.0.18

3 years ago

0.0.16

3 years ago

0.0.14

3 years ago

0.0.15

3 years ago

0.0.13

3 years ago

0.0.12

3 years ago

0.0.11

3 years ago

0.0.10

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago