Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apicase

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apicase - npm Package Compare versions

Comparing version 0.3.1 to 0.3.2

src/errors.js

2

package.json
{
"name": "apicase",
"version": "0.3.1",
"version": "0.3.2",
"description": "Create, group and manage your APIs with json declaration",

@@ -5,0 +5,0 @@ "author": "Anton Kosykh",

@@ -26,15 +26,30 @@ import * as Utils from './utils'

},
// Normalize and add mixin
addMixin (name, mixin) {
this.mixins[name] = Utils.normalizeMixin(mixin)
},
// Normalize and add hook
addHook (name, hook) {
this.hooks[name].push(Utils.normalizeHook(hook))
},
// Add hooks list
addHooks (list) {
merge(this.hooks, Utils.normalizeHooks(list))
},
// Add service in container
// unfolds children services (if exists)
addService (name, service) {
this.services[name] = createService(service, result)
set(this.services, name, createService(service, result))
if (!service.children) {
this.services[name] = service
return
}
Object.assign(
this.services,
mapValues(
Utils.flatServices({ name: service }),
service => createService(service, this)
)
)
},
// Call service
async go (name, data, options = {}) {

@@ -45,2 +60,10 @@ return await this.services[name].go(data, options)

if (config.base) {
result.base = config.base
}
if (config.headers) {
result.headers = config.headers
}
if (config.services) {

@@ -52,5 +75,7 @@ result.services = mapValues(

}
if (config.hooks) {
result.addHooks(config.hooks)
}
if (config.mixins) {

@@ -61,11 +86,18 @@ forEach(config.mixins, (mixin, name) => {

}
if (config.headers) {
result.headers = config.headers
}
if (config.base) {
result.base = config.base
}
// Add nested variant for services
// Note that you should not use reserved words for service names
// It can cause unexpected behavior
// TODO: show warning on using bad names for services
Object.defineProperty(result, 'tree', {
get () {
return zipObjectDeep(
Object.keys(this.services).map(item => item.split('/').join('.')),
Object.values(this.services)
)
}
})
return result
}
import Service from './service.js'
import Container from './container.js'
import { mergeHooksList } from './utils.js'
import { ApiAbort, ApiError } from './errors'
export default {
module.exports = {
ApiAbort,
ApiError,
Service,

@@ -7,0 +10,0 @@ Container,

import * as Utils from './utils'
import omit from 'lodash-es/omit'
import mapValues from 'lodash-es/mapValues'
export default function createResult (service) {
return {
let result = {
ok: false,
query: null,
headers: null,
body: null,
pending: false,
aborted: false,
ok: false,
reason: null,
response: null,
result: null,
// Set query
setQuery (query) {
this.query = query
},
// Set headers
setHeaders (headers) {
this.headers = headers
},
// Set response and result
setResult (response, res = undefined) {

@@ -27,6 +31,14 @@ this.response = response

},
// Set aborted flag
// set abort reason or null
setAborted (reason = null) {
this.aborted = true
this.reason = reason
},
// Normalize new mixins
// merge it with already added
setMixins (list) {
Object.defineProperties(this, mapValues(
Object.assign(
{}.
{},
service.container.mixins,

@@ -40,2 +52,18 @@ service.config.mixins,

}
// Returns clean data without methods
Object.defineProperty(result, 'clean', {
get () {
return omit(this, [
'clean',
'setQuery',
'setResult',
'setMixins',
'setAborted',
'setHeaders'
])
}
})
return result
}
import * as Utils from './utils'
import { ApiAbort } from './errors'
import createResult from './result'

@@ -14,2 +15,3 @@

// Merge hooks
let prepareHooks = function (hooks = {}) {

@@ -23,2 +25,3 @@ return Utils.mergeHooksList(

// Merge mixins
let prepareMixins = function (mixins = {}) {

@@ -32,2 +35,4 @@ return Object.assign(

// Add query string for GET requests
// return path-to-regexp method
let prepareUrl = function (data = {}) {

@@ -42,2 +47,3 @@ let url = `${state.container.base}${state.config.url}`

// Generate options object for fetch
let prepareOptions = function (data, headers) {

@@ -51,2 +57,3 @@ return {

// Merge headers
let prepareHeaders = function (headers = {}) {

@@ -67,2 +74,3 @@ let normalizeHeaders = (headers) =>

// Returns corrected request body object
let prepareBody = function (data = {}) {

@@ -76,2 +84,3 @@ return state.config.method === 'GET'

// Prepare query callback
let prepareCallback = function (params = {}) {

@@ -104,28 +113,28 @@ let self = state

let prepareBeforeHook = function (hook) {
// Wrap before hook in function
// with abort features
let prepareBeforeHook = function (hook, temp) {
return async (ctx, next) => {
let result
let abortInfo = {}
await hook.handler(
ctx,
(data, abortData = {}) => {
result = data
abortInfo = abortData
(data = undefined) => {
if (data === false) {
temp.abort = true
return
}
if (data instanceof ApiAbort) {
temp.abort = data
return
}
if (data !== undefined) {
ctx.query = data
}
}
)
switch (result) {
case undefined:
next()
break
case false:
ctx.aborted = true
ctx.abortInfo = abortInfo
break
default:
ctx.query = result
next()
}
if (!temp.abort) next()
}
}
// Wrap success and after hooks in function
// that no need to call next()
let prepareAfterHook = function (hook) {

@@ -138,2 +147,11 @@ return async (ctx, next) => {

// Wrap aborted hook in function
// with abort reason in second argument
let prepareAbortedHook = function (hook, reason) {
return async (ctx, next) => {
await hook.handler(ctx, reason)
next()
}
}
let state = {

@@ -161,42 +179,73 @@ config,

result.setQuery(data)
result.aborted = false
let callback = prepareCallback(omit(params, ['hooks', 'mixins']))
let queue = [
...hooks.before.map(prepareBeforeHook),
callback
]
return new Promise(async (resolve) => {
let endCallback = (ctx, next) => {
this.calls++
resolve(ctx)
resolve(ctx.clean)
next()
}
try {
await compose(hooks.before.map(prepareBeforeHook))(result)
if (result.aborted) {
if ('type' in result.abortInfo) {
await compose(hooks[result.abortInfo.type].map(prepareAfterHook))(result)
let temp = {
abort: false
}
await compose(
hooks.before.map(hook => prepareBeforeHook(hook, temp))
)(result)
// If call is aborted in before hook
if (temp.abort) {
// next(false)
if (temp.abort === true) {
result.setAborted(null)
return
}
if ('name' in result.abortInfo) {
if (typeof temp.abort !== 'object') {
throw new Error('Abort info should be an object')
}
result.setAborted(temp.abort.reason)
// next(new ApiAbort(data, { type: 'error' }))
if (temp.abort.info.type) {
await compose(hooks[temp.abort.info.type].map(prepareAfterHook))(result)
}
// next(new ApiAbort(data, { name: 'someHook' }))
if (temp.abort.info.name) {
let abortHooks = flatten(values(hooks))
if (!abortHooks.length) return
await compose(abortHooks.map(prepareAfterHook))(result)
await compose(
abortHooks.map(prepareAfterHook)
)(result)
}
return
// next(new ApiAbort(reason))
if (!temp.abort.info.type && !temp.abort.info.name) {
await compose(
hooks.aborted.map(hook => prepareAbortedHook(hook, temp.abort.reason))
)(result)
}
} else {
// Start query
result.pending = true
await callback(result)
result.pending = false
// Success hooks
await compose(
hooks.success.map(prepareAfterHook)
)(result)
}
result.pending = true
await callback(result)
result.pending = false
await compose(hooks.success.map(prepareAfterHook))(result)
} catch (err) {
// Log error in debug mode
if (this.container.debug) {
console.error(err)
}
result.pending = false
await compose(hooks.error.map(prepareAfterHook))(result)
// Call error hooks
if (result.aborted) return
await compose(
hooks.error.map(prepareAfterHook)
)(result)
} finally {
await compose([
...hooks.finished.map(prepareAfterHook),
endCallback
])(result)
if (result.aborted) return
await compose(
hooks.finished.map(prepareAfterHook).concat(endCallback)
)(result)
}

@@ -203,0 +252,0 @@ })

@@ -13,2 +13,3 @@ import pick from 'lodash-es/pick'

// Convert mixin to getter
export const normalizeMixin = function (mixin) {

@@ -31,2 +32,3 @@ if (isFunction(mixin)) {

// Convert hook into { name, handler } object
export const normalizeHook = function (hook) {

@@ -48,2 +50,3 @@ if (isFunction(hook)) {

// Normalize hooks array
export const normalizeHooks = function (hooks) {

@@ -53,11 +56,12 @@ return mapValues(

(hooks, hookType) =>
Array.isArray(hooks)
? hooks.map(normalizeHook)
: [hooks].map(normalizeHook)
flatten([hooks]).map(normalizeHook)
)
}
// Normalize hooks object
// add missed hook types arrays
// add new hooks into result object
export const mergeHooksList = function (...lists) {
return mergeWith(
{ before: [], success: [], error: [], finished: [] },
{ before: [], success: [], error: [], finished: [], aborted: [] },
...lists,

@@ -71,2 +75,4 @@ (a, b) =>

// Convert services with children
// into flat object with `service/nested/name` keys
export const flatServices = function (services, alias = '') {

@@ -83,2 +89,3 @@ let result = {}

// Convert json object to query string
export const jsonToQueryString = json => {

@@ -85,0 +92,0 @@ return !isPlainObject(json) || !Object.keys(json).length

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

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