Skip to content

Commit

Permalink
Introduce adjust function (issue #26)
Browse files Browse the repository at this point in the history
  • Loading branch information
yumauri committed Feb 7, 2021
1 parent 70885ee commit 65abf28
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 1 deletion.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,31 @@ const toMergedPDF = pipe(
)
```

## Advanced fine adjustment

There is special function `adjust`, which you can use to modify _any_ field in prepared internal `Request` object. You can check internal `Request` object structure in types. Any object, passed to `adjust`, will be merged with prepared `Request`.

For example, you can modify `url`, if your Gotenberg instance is working behind reverse proxy with some weird url replacement rules:

```typescript
import { pipe, gotenberg, convert, html, adjust, please } from 'gotenberg-js-client'

// Original Gotenberg HTML conversion endpoint is
// -> /convert/html
// But your reverse proxy uses location
// -> /hidden/html/conversion
const toPDF = pipe(
gotenberg('http://localhost:3000'),
convert,
html,
adjust({ url: '/hidden/html/conversion' }),
please
)
```

But, using that function, remember about Peter Parker principle:
> "With great power comes great responsibility"
## Bonus

If you happen to use this package from JavaScript, you will, obviously, lost type safety, but in return, you can use [proposed pipe operator](https://github.com/tc39/proposal-pipeline-operator) (with [Babel plugin](https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator)), to get beauty like this:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{
"path": "pkg/dist-node/index.js",
"webpack": false,
"limit": "4119 B"
"limit": "4216 B"
}
],
"@pika/pack": {
Expand Down
29 changes: 29 additions & 0 deletions src/adjust.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Request } from './_types'

/**
* Recursively merge requests
*/
const merge = <RequestEx extends Request>(request: RequestEx, modify: Partial<Request>) => {
const result = { ...request, ...modify }

for (const key in modify) {
if (
modify[key] &&
request[key] &&
typeof modify[key] === 'object' &&
typeof request[key] === 'object'
) {
result[key] = merge(request[key], modify[key])
}
}

return result
}

/**
* Adjust any Request *object* fields, for any request
* @return new typed Request, doesn't modify original Request
*/
export const adjust: {
<RequestEx extends Request>(modify: Partial<Request>): (request: RequestEx) => RequestEx
} = (modify) => (request) => merge(request, modify)
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { html } from './html'
export { url } from './url'

// export modifiers functions and constants
export { adjust } from './adjust'
export { add } from './add'
export { set } from './set'
export { to } from './to'
Expand Down
59 changes: 59 additions & 0 deletions test/adjust.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { adjust, Request, RequestType } from '../src'

// dumb object to test purity
const dumb: Request = {
type: RequestType.Undefined,
url: 'test',
fields: {
scale: 1,
landscape: true,
pageRanges: '1-2',
},
client: {
post: () => {
throw new Error('not implemented')
},
},
}

test('Should adjust flat fields', () => {
expect(adjust({})(dumb)).toEqual({ ...dumb })
expect(adjust({ url: 'changed' })(dumb)).toEqual({ ...dumb, url: 'changed' })
})

test('Should adjust deep fields', () => {
expect(adjust({ fields: { landscape: false } })(dumb)).toEqual({
...dumb,
fields: {
...dumb.fields,
landscape: false,
},
})
expect(adjust({ headers: { Authorization: 'Bearer token' } })(dumb)).toEqual({
...dumb,
headers: {
Authorization: 'Bearer token',
},
})
expect(
adjust({ headers: { Authorization: 'Bearer token' } })({
...dumb,
headers: { 'X-Header': 'test' },
})
).toEqual({
...dumb,
headers: {
Authorization: 'Bearer token',
'X-Header': 'test',
},
})
})

test('Should replace deep fields', () => {
expect(
adjust({ headers: { Authorization: 'Bearer token' } })({
...dumb,
headers: { Authorization: 'Basic dXNlcjpwYXNzd29yZA==' },
})
).toEqual({ ...dumb, headers: { Authorization: 'Bearer token' } })
})

0 comments on commit 65abf28

Please sign in to comment.