New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More ā†’
Socket
Sign inDemoInstall
Socket

docs-server

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

docs-server - npm Package Compare versions

Comparing version 0.3.0 to 1.0.0

dist/routers/extra-routes.js

10

CHANGELOG.md

@@ -0,1 +1,11 @@

<a name="0.3.0"></a>
# [0.3.0](https://github.com/lbwa/docs-server/compare/v0.2.0...v0.3.0) (2018-07-25)
### Features
* **Application:** expose application.server and application.gen ([08a0c45](https://github.com/lbwa/docs-server/commit/08a0c45))
<a name="0.2.0"></a>

@@ -2,0 +12,0 @@ # [0.2.0](https://github.com/lbwa/docs-server/compare/v0.1.2...v0.2.0) (2018-07-24)

20

dist/controllers/error.js

@@ -12,11 +12,13 @@ "use strict";

const { stringify } = require('../utils/index');
module.exports = (ctx, next) => __awaiter(this, void 0, void 0, function* () {
ctx.status = 404;
ctx.body = stringify({
errno: 1,
message: '[Error]: Invalid request'
module.exports = function (status = 404) {
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
ctx.status = status;
ctx.body = stringify({
errno: 1,
message: '[Error]: Invalid request'
});
ctx.set({
'Content-Type': 'application/json; charset=utf-8'
});
});
ctx.set({
'Content-Type': 'application/json; charset=utf-8'
});
});
};

@@ -20,3 +20,3 @@ "use strict";

}
activate({ cwd, catalogOutput }) {
activate({ cwd, dest }) {
return __awaiter(this, void 0, void 0, function* () {

@@ -30,6 +30,6 @@ let headMeta;

}
fs.writeFile(catalogOutput, headMeta, (err) => {
fs.writeFile(dest, headMeta, (err) => {
err
? console.error(err)
: console.log(`\nšŸ‘Œ generate menu successfully in ${catalogOutput} ! \n`);
: console.log(`\nšŸ‘Œ generate menu successfully in ${dest} ! \n`);
});

@@ -36,0 +36,0 @@ return this;

@@ -18,7 +18,16 @@ "use strict";

class Application {
constructor({ cwd = resolve('/'), catalogOutput = resolve('/menu.json'), port = '8800' } = {}) {
constructor({ cwd = resolve('/'), dest = resolve('/menu.json'), port = '8800', extra = [] } = {}) {
if (!(this instanceof Application)) {
return new Application({
cwd,
dest,
port,
extra
});
}
this.options = {
cwd,
catalogOutput,
port
dest,
port,
extra
};

@@ -30,15 +39,20 @@ this.activate();

const options = this.options;
this.server = this.activateServer();
this.gen = yield this.activateGenerator(options.cwd, options.catalogOutput);
this.genPromise = this.activateGenerator(options.cwd, options.dest);
this.gen = yield this.genPromise;
this.server = this.activateServer(this.gen.contentList, options.extra, options.dest);
});
}
activateGenerator(cwd, catalogOutput) {
activateGenerator(cwd, dest) {
return gen.activate({
cwd,
catalogOutput
dest
});
}
activateServer() {
activateServer(contentList, extra, dest) {
const port = this.options.port;
const server = new Server();
const server = new Server({
contentList,
extra,
dest
});
return server.listen(port, () => {

@@ -48,6 +62,3 @@ console.log(`\nServer is listening on http://localhost:${port}\n`);

}
handleError(err) {
console.error(err);
}
}
module.exports = Application;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Router = require("koa-router");
const config = require('../config/index');
const logger = require('../utils/logger');
const home = require('../controllers/home');
const docs = require('../controllers/docs');
const error = require('../controllers/error');
const createErrorHandle = require('../controllers/error');
const createExtraRoutes = require('./extra');
const createMenuRoute = require('./menu');
const router = new Router();
const routes = config.routes;
const docsPath = config.docsPath;
router
.get('/', home);
for (let route of routes) {
const format = /^\//.test(route.path) ? route.path : `/${route.path}`;
router
.get(format, route.callback);
function createRoutes(contentList, extra, dest) {
const docsRoutes = Object.keys(contentList);
router.get('/', home);
for (let route of docsRoutes) {
const formatRoute = /^\//.test(route) ? route : `/${route}`;
router.get(formatRoute, docs);
logger.info(`[Server]`, `Generate route: ${route}`);
}
createMenuRoute(extra, dest, router);
createExtraRoutes(extra, router);
return router;
}
router
.get(`/${docsPath}/:id`, docs)
.get('*', error);
module.exports = router;
module.exports = function createRouter(contentList, extra, dest) {
createRoutes(contentList, extra, dest)
.get('*', createErrorHandle(404))
.all('*', createErrorHandle(405));
return router;
};

@@ -13,3 +13,3 @@ "use strict";

const compress = require("koa-compress");
const router = require('./routers/index');
const createRouter = require('./routers/index');
const { stringify } = require('./utils/index');

@@ -61,3 +61,3 @@ const isTest = process.env.NODE_ENV === 'test';

class Server extends Koa {
constructor({ customHeaders = {}, threshold = 1 } = {}) {
constructor({ customHeaders = {}, threshold = 1, contentList = {}, extra = [], dest = './menu.json' } = {}) {
super();

@@ -67,3 +67,3 @@ this.setIOMiddleware();

this.setGzip(threshold);
this.setRouter();
this.setRouter(contentList, extra, dest);
}

@@ -81,3 +81,4 @@ setIOMiddleware() {

}
setRouter() {
setRouter(contentList, extra, dest) {
const router = createRouter(contentList, extra, dest);
this.use(router.routes());

@@ -84,0 +85,0 @@ this.use(router.allowedMethods());

{
"name": "docs-server",
"version": "0.3.0",
"version": "1.0.0",
"description": "A server which is used to build one of microservices for docs system",

@@ -23,3 +23,3 @@ "main": "dist/index.js",

"clean": "rm -vrf dist/*",
"test": "yarn ts && cross-env NODE_ENV=test npx mocha test/http.spec.js",
"test": "yarn ts && cross-env NODE_ENV=test npx mocha test/app.spec.js",
"changelog": "npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0",

@@ -49,2 +49,3 @@ "release": "sh scripts/release.sh"

"mocha": "^5.2.0",
"supertest": "^3.1.0",
"typescript": "^2.9.2"

@@ -51,0 +52,0 @@ },

@@ -7,79 +7,64 @@ # Docs-server [![npm](https://img.shields.io/npm/v/docs-server.svg)](https://www.npmjs.com/package/docs-server) [![CircleCI](https://circleci.com/gh/lbwa/docs-server.svg?style=svg)](https://circleci.com/gh/lbwa/docs-server) [![node](https://img.shields.io/node/v/docs-server.svg)](https://www.npmjs.com/package/docs-server)

- Perform markdown searching and generate correct dynamic routes according to root path.
- Perform automatic markdown searching and generate correct dynamic routes according to the root path of your project.
- Support for specifying additional static routes.
- Support multiple-level documentation routes.
## Notice
- Support for specifying additional static resources routes.
Only support second-level directory temporarily.
## Usage
Your project structure should be like this:
- Simple running
```markdown
ā”œā”€ā”€ doc [custom directory name]
| ā”œā”€ā”€ a.md
| ā”œā”€ā”€ b.md
| ā”œā”€ā”€ c.md
| ā””ā”€ā”€ d.md
|
ā”œā”€ā”€ docs-server.config.js [define your custom config]
|
ā”œā”€ā”€ something.json [additional static route]
|
...
ā””ā”€ā”€ package.json
```js
const DocsServer = require('docs-server')
// It should be running at http://localhost:8800 by default
const app = new DocsServer()
```
## Usage
or
1. You should specify your documents directory.
```js
const DocsServer = require('docs-server')()
```
- ( Optional ) You can specify your custom configuration.
```js
// docs-server.config.js
const send = require('koa-send')
const resolve = require('path').resolve
const DocsServer = require('docs-server')
module.exports = {
// documents directory (required)
// based on root path
docsPath: 'doc',
// Notice: all options is optional
const app = new DocsServer({
// should be nodejs current working directory
cwd: resolve('./'),
// extra static file route (optional)
routes: [
// the output path of catalog files (based on current working directory)
dest: resolve('./menu.json'),
// your server running port
port: '8800',
// extra static resource routes
extra: [
{
path: 'menu',
callback: async (ctx, next) => {
await send(ctx, './menu.json', {
root: resolve(__dirname, './')
})
route: '/test', // eg. http://locahost:8800/test
middleware: async (ctx, next) => {
// do something
}
},
{
path: 'something',
callback: async (ctx, next) => {
await send(ctx, './something.json', {
root: resolve(__dirname, './')
})
}
}
]
}
})
```
2. Import module and run it
- Test you building
```js
const DocsServer = require('docs-server')
// It should be running at http://localhost:8800 by default
const app = new DocsServer()
```powershell
# test your server
curl -v http://localhost:8800 # response from /
curl -v http://localhost:8800/doc/sample # response from /doc/sample
```
3. ( Optional ) You can specify output path of catalog file ( menu.json ) and server port.
## CHANGELOG
```js
const app = new DocsServer({
catalogOutput: path.resolve(__dirname, './')
port: '3000'
})
```
[CHANGELOG](./CHANGELOG.md)

@@ -0,1 +1,3 @@

import Koa = require('koa')
export interface resHeaders {

@@ -32,10 +34,11 @@ [key: string]: string

cwd: string
catalogOutput: string
dest: string
}
export interface appOptions {
export interface appOptions {
cwd?: string
catalogOutput?: string
dest?: string
port?: number | string
directory?: string
extra?: extraRoute[]
}

@@ -46,2 +49,10 @@

threshold?: number
contentList?: contentList
extra?: extraRoute[]
dest?: string
}
export interface extraRoute {
route?: string
middleware?: (ctx: Koa.Context, next: Function) => {}
}

@@ -0,0 +0,0 @@ import Koa = require('koa')

import Koa = require('koa')
const { stringify } = require('../utils/index')
module.exports = async (ctx: Koa.Context, next: Function) => {
ctx.status = 404
ctx.body = stringify({
errno: 1,
message: '[Error]: Invalid request'
})
ctx.set({
'Content-Type': 'application/json; charset=utf-8'
})
module.exports = function (status: number = 404) {
return async (ctx: Koa.Context, next: Function) => {
ctx.status = status
ctx.body = stringify({
errno: 1,
message: '[Error]: Invalid request'
})
ctx.set({
'Content-Type': 'application/json; charset=utf-8'
})
}
}

@@ -18,4 +18,11 @@ import { meta, post, initialContent, contentList, targetPath } from './config/types'

// extract function named `activate` for getting a Promise object
async activate ({ cwd, catalogOutput }: targetPath) {
/**
* activate Generator
* extract function named `activate` for getting a Promise object
*
* @param {targetPath} { cwd, dest }working path and output path
* @returns generator instance
* @memberof Gen
*/
async activate ({ cwd, dest }: targetPath) {
let headMeta: string

@@ -29,6 +36,6 @@

fs.writeFile(catalogOutput, headMeta, (err: object) => {
fs.writeFile(dest, headMeta, (err: object) => {
err
? console.error(err)
: console.log(`\nšŸ‘Œ generate menu successfully in ${catalogOutput} ! \n`)
: console.log(`\nšŸ‘Œ generate menu successfully in ${dest} ! \n`)
})

@@ -39,2 +46,9 @@

/**
*activate scanner
*
* @param {string} path working path
* @returns {Promise<catalog>}
* @memberof Gen
*/
async parser (path: string) {

@@ -104,2 +118,9 @@ let catalog: post[] = []

/**
*scan all markdown files in project
*
* @param {string} cwd the beginning of working path
* @returns {Promise<singleDocDate>[]}
* @memberof Gen
*/
async scanner (cwd: string) {

@@ -130,2 +151,9 @@ let docsPath: string[] = []

/**
*generate all path
*
* @param {string} cwd working path
* @returns {Promise<string[]>} a Array instance including all path
* @memberof Gen
*/
getDocsPath (cwd: string): Promise<string[]> {

@@ -143,2 +171,9 @@ return new Promise((resolve, reject) => {

/**
*read specific file by async
*
* @param {string} target target file
* @returns Promise<err | file data>
* @memberof Gen
*/
readFile (target: string) {

@@ -145,0 +180,0 @@ // `target` just like 'do/sample/.../sample.md'

@@ -1,2 +0,2 @@

import { appOptions } from './config/types'
import { appOptions, extraRoute } from './config/types'
import Gen from './generator'

@@ -9,2 +9,7 @@ import http = require('http')

/**
*
* @param {string} dir path
* @returns {string} path based on current working directory of nodejs process
*/
function resolve (dir: string): string {

@@ -14,5 +19,13 @@ return join(process.cwd(), dir)

/**
* @class Application
* @param {String} cwd current working directory(should be a absolute path)
* @param {String} dest the output path of menu.json(should be a absolute path)
* @param {String} port server port
* @param {extraRoute[]} extra extra static resources routes
*/
class Application {
options: appOptions
server: http.Server // http.Server -> server.close
server: http.Server // http.Server -> to expose `server.close` function
genPromise: Promise<Gen>
gen: Gen

@@ -23,13 +36,24 @@

cwd = resolve('/'),
catalogOutput = resolve('/menu.json'),
port = '8800'
dest = resolve('/menu.json'),
port = '8800',
extra = []
}: appOptions = {}
) {
if (!(this instanceof Application)) {
return new Application({
cwd,
dest,
port,
extra
})
}
this.options = {
cwd,
catalogOutput,
port
dest,
port,
extra
}
this.activate()
// this.server has a value, this.gen is undefined on this position
}

@@ -40,21 +64,36 @@

// To expose this.server when Application instantiation
// Make sure this.activateServer() before this.activateGenerator()
// Router's docs controller sync with gen.contentList
this.server = this.activateServer()
/**
* 1. this.activeGenerator will be invoked immediately
* 2. async function will be restore execution (enter microtask queue)
* until Application complete instantiation which means current event loop
* completed.
* 3. this.gen is valid until microtask complete
* 2. this.gen must be pending status promise when instantiation completed
*/
this.gen = await this.activateGenerator(options.cwd, options.catalogOutput)
this.genPromise = this.activateGenerator(options.cwd, options.dest)
/**
* 1. async function wouldn't restore execution (enter microtask queue)
* until Application complete instantiation which means all mission
* in the current (macro-)task queue has been completed
* 2. this.gen is invalid until Application complete this own initialization
*/
this.gen = await this.genPromise
// Doesn't be invoked until generator complete mission
this.server = this.activateServer(
this.gen.contentList,
options.extra,
options.dest
)
}
activateGenerator (cwd: string, catalogOutput: string) {
/**
*activate generator
*
* @param {string} cwd project root path(current working directory)
* @param {string} dest the output path of menu.json
* @returns {Gen} Generator instance
* @memberof Application
*/
activateGenerator (cwd: string, dest: string) {
return gen.activate({
cwd,
catalogOutput
dest
})

@@ -64,5 +103,17 @@ }

// ! Notice: Make sure `this` value equal to Application instance
activateServer () {
/**
*build local server
*
* @param {Gen['contentList']} contentList content storage
* @param {extraRoute[]} extra extra static resources routes
* @returns {http.Server} http.Server instance
* @memberof Application
*/
activateServer (contentList: Gen['contentList'], extra: extraRoute[], dest: string):http.Server {
const port = this.options.port
const server = new Server()
const server = new Server({
contentList,
extra,
dest
})
return server.listen(port, () => {

@@ -72,8 +123,4 @@ console.log(`\nServer is listening on http://localhost:${port}\n`)

}
handleError (err: Error) {
console.error(err)
}
}
module.exports = Application
import Router = require('koa-router')
import { contentList, extraRoute } from '../config/types'
const config = require('../config/index')
const logger = require('../utils/logger')
const home = require('../controllers/home')
const docs = require('../controllers/docs')
const error = require('../controllers/error')
const createErrorHandle = require('../controllers/error')
const createExtraRoutes = require('./extra')
const createMenuRoute = require('./menu')
const router = new Router()
const routes = config.routes
const docsPath = config.docsPath
/**
* create all routes based on configuration
*
* @param {contentList} contentList content storage
* @param {extraRoute[]} extra extra static resources routes
* @returns a koa router instance
*/
function createRoutes (
contentList: contentList,
extra: extraRoute[],
dest: string
) {
const docsRoutes = Object.keys(contentList)
router
.get('/', home)
router.get('/', home)
for (let route of routes) {
const format = /^\//.test(route.path) ? route.path : `/${route.path}`
router
.get(format, route.callback)
for (let route of docsRoutes) {
const formatRoute = /^\//.test(route) ? route : `/${route}`
router.get(formatRoute, docs)
logger.info(`[Server]`, `Generate route: ${route}`)
}
// Make sure createMenuRoute before createExtraRoutes
createMenuRoute(extra, dest, router)
createExtraRoutes(extra, router)
return router
}
router
// only file name
.get(`/${docsPath}/:id`, docs)
.get('*', error)
/**
* create a koa router instance
*
* @param {contentList} contentList content storage
* @param {extraRoute[]} extra extra static resources routes
* @returns a koa router instance
*/
module.exports = function createRouter (
contentList: contentList,
extra: extraRoute[],
dest: string
) {
createRoutes(contentList, extra, dest)
.get('*', createErrorHandle(404))
.all('*', createErrorHandle(405))
module.exports = router
return router
}

@@ -5,3 +5,3 @@ import Koa = require('koa')

const router = require('./routers/index')
const createRouter = require('./routers/index')
const { stringify } = require('./utils/index')

@@ -52,5 +52,17 @@ const isTest = process.env.NODE_ENV === 'test'

/**
*create a server instance based on Koa
*
* @class Server
* @extends {Koa}
*/
class Server extends Koa {
// Once params is empty object, customHeaders and threshold will be set default value
constructor ({ customHeaders={}, threshold=1 }: server = {}) {
constructor ({
customHeaders={},
threshold=1,
contentList = {},
extra = [],
dest = './menu.json'
}: server = {}) {
super()

@@ -60,3 +72,3 @@ this.setIOMiddleware()

this.setGzip(threshold)
this.setRouter()
this.setRouter(contentList, extra, dest)
}

@@ -78,3 +90,8 @@

setRouter () {
setRouter (
contentList: server['contentList'],
extra: server['extra'],
dest: server['dest']
) {
const router = createRouter(contentList, extra, dest)
this.use(router.routes())

@@ -81,0 +98,0 @@ this.use(router.allowedMethods())

@@ -0,0 +0,0 @@ const stringify = JSON.stringify.bind(JSON)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with āš”ļø by Socket Inc