Skip to content

Commit

Permalink
Merge pull request #10 from jeffijoe/chore/gha
Browse files Browse the repository at this point in the history
Upgrade packages, move to GitHub Actions, use fast-glob
  • Loading branch information
jeffijoe committed Feb 15, 2024
2 parents 5b6fd88 + e574ee7 commit 34bea0a
Show file tree
Hide file tree
Showing 21 changed files with 21,405 additions and 6,984 deletions.
28 changes: 28 additions & 0 deletions .eslintrc.cjs
@@ -0,0 +1,28 @@
/* eslint-env node */
module.exports = {
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
root: true,
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
rules: {
// Only disabling this because this code is very old but also battle-tested,
// and coming up with clever typings may break for consumers.
'@typescript-eslint/no-explicit-any': 'off',
// We need to support `Function` and `Constructor` types.
'@typescript-eslint/ban-types': 'off',
},
overrides: [
{
files: ['**/__tests__/*.test.ts'],
rules: {
// The tests may use an untyped library which requires (no pun intended) `require`.
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
],
}
65 changes: 65 additions & 0 deletions .github/workflows/ci.yml
@@ -0,0 +1,65 @@
# Name of the pipeline
name: CI

# Allow the token to create releases and read pull requests.
# Needed for semantic-release.
permissions:
contents: write
pull-requests: read

# When pushing to `master` or when there is a PR for the branch.
on:
pull_request:
push:
branches:
- 'master'

jobs:
ci:
name: Lint, Test & Release (Node ${{ matrix.version }})
runs-on: ubuntu-22.04
strategy:
fail-fast: true
matrix:
version:
- 16
- 18
- 20
- current
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
cache: 'npm'

- name: Install Packages
run: npm ci

- name: Build
run: npm run build

- name: Lint
run: npm run lint

- name: Test
run: npm run cover

- if: ${{ matrix.version == 'current' }}
name: Coveralls
uses: coverallsapp/github-action@v2

- if: ${{ matrix.version == 'current' }}
name: Semantic Release
run: npm run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

# Cancel running workflows for the same branch when a new one is started.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
30 changes: 0 additions & 30 deletions .travis.yml

This file was deleted.

2 changes: 2 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,7 @@
# Changelog

> See the [Releases](https://github.com/jeffijoe/awilix-router-core/releases) page for the changelog going forward.
## 1.6.1

- Handle falsy values in `getState`
Expand Down
101 changes: 55 additions & 46 deletions README.md
Expand Up @@ -12,26 +12,27 @@
# Table of Contents

* [Install](#install)
* [Example](#example)
* [With decorators](#with-decorators)
* [With builder pattern](#with-builder-pattern)
* [For framework adapter authors](#for-framework-adapter-authors)
* [API](#api)
* [Route Declaration](#route-declaration)
* [Builder](#builder)
* [createController(targetClassOrFunction)](#createcontrollertargetclassorfunction)
* [Decorators](#decorators)
* [route(path)](#routepath)
* [before(middlewares) and <code>after(middlewares)</code>](#beforemiddlewares-and-aftermiddlewares)
* [verbs(httpVerbs)](#verbshttpverbs)
* [Verb shorthands](#verb-shorthands)
* [Extracting route config](#extracting-route-config)
* [getStateAndTarget(functionOrClassOrController)](#getstateandtargetfunctionorclassorcontroller)
* [rollUpState(state)](#rollupstatestate)
* [findControllers(pattern, globOptions)](#findcontrollerspattern-globoptions)
* [Author](#author)

- [awilix-router-core](#awilix-router-core)
- [Table of Contents](#table-of-contents)
- [Install](#install)
- [Example](#example)
- [With decorators](#with-decorators)
- [With builder pattern](#with-builder-pattern)
- [For framework adapter authors](#for-framework-adapter-authors)
- [API](#api)
- [Route Declaration](#route-declaration)
- [Builder](#builder)
- [`createController(targetClassOrFunction)`](#createcontrollertargetclassorfunction)
- [Decorators](#decorators)
- [`route(path)`](#routepath)
- [`before(middlewares)` and `after(middlewares)`](#beforemiddlewares-and-aftermiddlewares)
- [`verbs(httpVerbs)`](#verbshttpverbs)
- [Verb shorthands](#verb-shorthands)
- [Extracting route config](#extracting-route-config)
- [`getStateAndTarget(functionOrClassOrController)`](#getstateandtargetfunctionorclassorcontroller)
- [`rollUpState(state)`](#rollupstatestate)
- [`findControllers(pattern, globOptions)`](#findcontrollerspattern-globoptions)
- [Author](#author)

# Install

Expand Down Expand Up @@ -66,12 +67,12 @@ import authenticate from 'your-framework-authentication'
@before(bodyParser())
@route('/news')
export default class NewsController {
constructor ({ service }) {
constructor({ service }) {
this.service = service
}

@GET()
async find (ctx) {
async find(ctx) {
ctx.body = await this.service.doSomethingAsync()
}

Expand All @@ -84,7 +85,7 @@ export default class NewsController {
@route('(/:id)')
@verbs([HttpVerbs.POST, HttpVerbs.PUT])
@before(authenticate())
async save (ctx) {
async save(ctx) {
ctx.body = await this.service.saveNews(ctx.params.id, ctx.request.body)
}
}
Expand All @@ -102,9 +103,11 @@ import authenticate from 'your-framework-authentication'
// Can use a factory function or a class.
const api = ({ service }) => ({
find: async () => (ctx.body = await service.doSomethingAsync()),
get: async (ctx) => (ctx.body = await service.getNewsOrWhateverAsync(ctx.params.id)),
save: async (ctx) => (ctx.body = await service.saveNews(ctx.params.id, ctx.request.body))
})
get: async (ctx) =>
(ctx.body = await service.getNewsOrWhateverAsync(ctx.params.id)),
save: async (ctx) =>
(ctx.body = await service.saveNews(ctx.params.id, ctx.request.body)),
})

export default createController(api)
.before(bodyParser())
Expand All @@ -113,7 +116,7 @@ export default createController(api)
.get('/:id', 'get') // <- "get" is the method on the result from `api`
.verbs([HttpVerbs.POST, HttpVerbs.PUT], '/:id', 'save', {
// "save" is the method on the result from `api`
before: [authenticate()]
before: [authenticate()],
})
```

Expand Down Expand Up @@ -145,18 +148,18 @@ Creates a controller that will invoke methods on an instance of the specified `t

The controller exposes the following builder methods:

* `.get|post|put|patch|delete|head|options|connect|all(path, method, opts)`: shorthands for `.verbs([HttpVerbs.POST], ...)` - see [`HttpVerbs`][http-verbs] for possible values.
* `.verbs(verbs, path, method, opts)`: registers a path mapping for the specified controller method.
* `.prefix(path)`: registers a prefix for the controller. Calling this multiple times adds multiple prefix options.
* `.before(middlewares)`: registers one or more middlewares that runs before any of the routes are processed.
* `.after(middlewares)`: registers one or more middlewares that runs after the routes are processed.
- `.get|post|put|patch|delete|head|options|connect|all(path, method, opts)`: shorthands for `.verbs([HttpVerbs.POST], ...)` - see [`HttpVerbs`][http-verbs] for possible values.
- `.verbs(verbs, path, method, opts)`: registers a path mapping for the specified controller method.
- `.prefix(path)`: registers a prefix for the controller. Calling this multiple times adds multiple prefix options.
- `.before(middlewares)`: registers one or more middlewares that runs before any of the routes are processed.
- `.after(middlewares)`: registers one or more middlewares that runs after the routes are processed.

The optional `opts` object passed to `.verbs` can have the following properties:

* `before`: one or more middleware that runs before the route handler.
* `after`: one or more middleware that runs after the route handler.
- `before`: one or more middleware that runs before the route handler.
- `after`: one or more middleware that runs after the route handler.

**Note**: all builder methods returns a _new builder_ - this means the builder is **immutable**! This allows you to have a common
**Note**: all builder methods returns a _new builder_ - this means the builder is **immutable**! This allows you to have a common
builder setup that you can reuse for multiple controllers.

### Decorators
Expand All @@ -166,10 +169,10 @@ If you have enabled decorator support in your transpiler, you can use the decora
The decorator API exports are:

```js
import {
route,
import {
route,
before,
after,
after,
verbs,
HttpVerbs,

Expand All @@ -182,7 +185,7 @@ import {
CONNECT,
OPTIONS,
PATCH,
ALL
ALL,
} from 'awilix-router-core'
```

Expand Down Expand Up @@ -233,7 +236,7 @@ class Controller {

**Class-level**: not allowed.

**Method-level**: adds HTTP verbs that the route will match.
**Method-level**: adds HTTP verbs that the route will match.

Has no effect if no `route`s are configured.

Expand Down Expand Up @@ -272,12 +275,16 @@ This section is for framework adapter authors. Please see [awilix-koa][awilix-ko

The primary functions needed for this are `getStateAndTarget`, `rollUpState`, and `findControllers`.

> **NOTE**: when referring to "state-target tuple", it means an object containing `state`
> and `target` properties, where `target` is the class/function to build up (using `container.build`)
> **NOTE**: when referring to "state-target tuple", it means an object containing `state`
> and `target` properties, where `target` is the class/function to build up (using `container.build`)
> in order to get an object to call methods on.
```js
import { getStateAndTarget, rollUpState, findControllers } from 'awilix-router-core'
import {
getStateAndTarget,
rollUpState,
findControllers,
} from 'awilix-router-core'
```

### `getStateAndTarget(functionOrClassOrController)`
Expand All @@ -290,13 +297,15 @@ This will return a map where the key is the controller method name and the value

### `findControllers(pattern, globOptions)`

Using `glob`, loads controllers from matched files, with non-applicable files filtered out.
Using `fast-glob`, loads controllers from matched files.

> Note: This uses `require` and so currently is not compatible with ESM.
Returns an array of state-target tuples.

# Author

Jeff Hansen — [@Jeffijoe](https://twitter.com/Jeffijoe)

[http-verbs]: /src/http-verbs.ts
[awilix-koa]: https://github.com/jeffijoe/awilix-koa
[http-verbs]: /src/http-verbs.ts
[awilix-koa]: https://github.com/jeffijoe/awilix-koa

0 comments on commit 34bea0a

Please sign in to comment.