Browse Source

work on method factory behvaiour with parsing its args

tags/v1.0.0-alpha.1
ojizero 1 year ago
parent
commit
a0a2f422d7
No account linked to committer's email address
4 changed files with 36 additions and 25 deletions
  1. 3
    3
      README.md
  2. 1
    1
      src/client.ts
  3. 27
    20
      src/method.ts
  4. 5
    1
      src/resource.ts

+ 3
- 3
README.md View File

@@ -86,7 +86,7 @@ export const someGetMethodWithParam = client.route({ path: '/some/path/:withInne
/* ******************* */

/// In your application
import YourAPIClient from 'your-client-module'
import * as YourAPIClient from 'your-client-module'

const someGetMethodPromise = YourAPIClient.someGetMethod() // GET http://some.base.url/some/path
const someGetMethodWithParamPromise = YourAPIClient.someGetMethodWithParam(5) // GET http://some.base.url/some/path/5
@@ -264,8 +264,8 @@ This is still a work in progress :D any help is appreciated
- [ ] Get `onError: resolve` to work
- [ ] Support simplified form for validation
- [ ] Finalize behvaiour of genreator method functions
- [ ] What to do with their arguments (ambiguity of options/payload/querystring in args)
- [ ] Support optional path arguments ?
- [x] What to do with their arguments (ambiguity of options/payload/querystring in args)
- [ ] Document internal method factory behvaiour
- [ ] ...

## License

+ 1
- 1
src/client.ts View File

@@ -1,4 +1,3 @@
import got from 'got'
import querystring from 'querystring'
import { IncomingHttpHeaders } from 'http';
import { OutgoingHttpHeaders } from 'http'
@@ -158,6 +157,7 @@ export class PortalClient implements Client {
json: isJson,
timeout: timeout * 1000,
throwHttpErrors: onError !== 'resolve',
// TODO: what if the payload is undefined ?
body: isJson ? payload : JSON.stringify(payload),
}
}

+ 27
- 20
src/method.ts View File

@@ -19,7 +19,6 @@ export interface MethodSpec {
queryString?: ValdiationSpec,
contentType?: string,
accept?: string,
// strict?: boolean,
headers?: OutgoingHttpHeaders,
}

@@ -57,36 +56,44 @@ export function methodGenerator (client: Client): MethodFactory {
let options

if (typeof args[length - 1] === 'object') {
// If the last argument it an
// object use it as options
options = args[length - 1]
args = args.slice(0, length - 1)
length -= 1
}

if (typeof args[length - 1] === 'object') {
// If the second to last argument it an
// object use it as a payload
payload = args[length - 1]
args = args.slice(0, length - 1)
length -= 1
} else if (
// TODO: ??? does this make sense ?
(typeof body !== 'undefined' || method === 'POST' || method === 'PUT')
&& typeof options !== 'undefined'
) {
const optionsHasPayload = 'payload' in options

payload = optionsHasPayload ? options.payload : options
options = optionsHasPayload ? options : undefined
} else if ((!!body) && typeof options !== 'undefined') {
// If paylaod is expected and options is defined use
// the last argument as payload instead of options
payload = options
options = undefined
}

if (typeof args[length - 1] === 'object') {
// If the third to last argument it an
// object use it as a query string
query = args[length - 1]
args = args.slice(0, length - 1)
length -= 1
} else if (typeof queryString !== 'undefined' && typeof options !== 'undefined') {
const optionsHasQueryString = 'queryString' in options

query = optionsHasQueryString ? options.queryString : options
options = optionsHasQueryString ? options : undefined
} else if (typeof queryString !== 'undefined' && typeof payload !== 'undefined') {
} else if ((!!queryString) && (!!body)) {
// Both query string and body are expected
if (method === 'GET') {
// For GET requests give precedence to query string
query = payload
payload = undefined
} else {
// For everything else give precedence to payload
query = undefined
}
} else if ((!!queryString) && (!body)) {
// Query string is expected but body isn't
query = payload
payload = undefined
}
@@ -95,16 +102,16 @@ export function methodGenerator (client: Client): MethodFactory {
ensureValidData(body, payload, 'Payload')
ensureValidData(queryString, query, 'Query string')

// Regexp here isn global we wanna
// Regexp here is global we wanna
// match all avaialbel parameters
let paramsCount = (path.match(/:[^\/:]+/g) || []).length
let paramsCount: number = (path.match(/:[^\/:]+/g) || []).length

let fullPath: string = args.reduce((acc, arg) => {
paramsCount -= 1

// Regexp here isn't global we wanna
// match the first parameter only
return acc.replace(/:[^\/:]+/, arg)
return acc.replace(/:[^\/:&?]+/, arg)
}, path)

if (paramsCount !== 0) throw new Error('Number of provided parameters does not macth request path arguments')
@@ -114,8 +121,8 @@ export function methodGenerator (client: Client): MethodFactory {
[ fullPath, attachedQuery ] = fullPath.split('?', 2)

query = {
...query,
...parseQuery(attachedQuery),
...query,
}

query = stringifyQuery(query)

+ 5
- 1
src/resource.ts View File

@@ -59,7 +59,8 @@ export class Resource {
}

initialize () {
this.enabledRoutes.forEach((route) => {
this.enabledRoutes.forEach(route => {
route = route.toLowerCase()
const routeMethod = this.methodFromRoute(route)

Object.defineProperty(this, route, {
@@ -89,6 +90,9 @@ export class Resource {

methodFromRoute (route: string) {
let spec = defaultBaseSpecs[route]

if (!spec) throw new Error(`An unsupported default route, ${route}, requested.`)

const prefix = this.baseRoute
const suffix = spec.path


Loading…
Cancel
Save