Skip to content

Commit

Permalink
Merge pull request #320 from zazuko/http-ts
Browse files Browse the repository at this point in the history
barnard59-http converted to TS
  • Loading branch information
tpluscode authored Aug 15, 2024
2 parents 61a1095 + 52227af commit 6ff3428
Show file tree
Hide file tree
Showing 20 changed files with 137 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-crews-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"barnard59-http": minor
---

Add overload to `get` and `post` to match the signature of native `fetch`
5 changes: 5 additions & 0 deletions .changeset/smooth-lamps-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"barnard59-http": patch
---

Added TS declarations
7 changes: 5 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 18 additions & 21 deletions packages/cli/test/barnard59.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('barnard59', function () {
describe('run', () => {
it('should suggest alternatives when multiple root pipelines exist', () => {
const pipelineFile = filenamePipelineDefinition('multiple-root')
const command = `barnard59 run ${pipelineFile}`
const command = `npx barnard59 run ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

Expand All @@ -21,7 +21,7 @@ describe('barnard59', function () {
})
it('should exit with error code 0 if there are no error while processing the pipeline', () => {
const pipelineFile = filenamePipelineDefinition('simple')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

Expand All @@ -30,7 +30,7 @@ describe('barnard59', function () {

it('should exit with error code 1 when an error in the pipeline occurs', () => {
const pipelineFile = filenamePipelineDefinition('error')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

Expand All @@ -40,7 +40,7 @@ describe('barnard59', function () {
describe('verbose', () => {
it('should log info messages if verbose flag is set', () => {
const pipelineFile = filenamePipelineDefinition('logs')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`

const result = stripAnsi(shell.exec(command, { cwd }).stderr)

Expand All @@ -49,7 +49,7 @@ describe('barnard59', function () {

it('all logs suppressed with --quiet flag', () => {
const pipelineFile = filenamePipelineDefinition('logs')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} -q`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} -q`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -58,7 +58,7 @@ describe('barnard59', function () {

it('should log info messages if verbose flag is set before command', () => {
const pipelineFile = filenamePipelineDefinition('logs')
const command = `barnard59 --verbose run --pipeline=http://example.org/pipeline/ ${pipelineFile}`
const command = `npx barnard59 --verbose run --pipeline=http://example.org/pipeline/ ${pipelineFile}`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -67,7 +67,7 @@ describe('barnard59', function () {

it('should not log debug messages if verbose flag is set', () => {
const pipelineFile = filenamePipelineDefinition('logs')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -76,7 +76,7 @@ describe('barnard59', function () {

it('should log trace messages if verbose flag is set 4 times', () => {
const pipelineFile = filenamePipelineDefinition('logs')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ -vvvv ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ -vvvv ${pipelineFile}`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -87,7 +87,7 @@ describe('barnard59', function () {
describe('variable', () => {
it('should set the given variable to the given value', () => {
const pipelineFile = filenamePipelineDefinition('simple')
const command = `barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} --variable=abc=123`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} --variable=abc=123`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -96,7 +96,7 @@ describe('barnard59', function () {

it('should set the given variable to the given value before command', () => {
const pipelineFile = filenamePipelineDefinition('simple')
const command = `barnard59 --variable=abc=123 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`
const command = `npx barnard59 --variable=abc=123 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile}`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -105,7 +105,7 @@ describe('barnard59', function () {

it('should set the given variable to the value of the environment variable with the same name', () => {
const pipelineFile = filenamePipelineDefinition('simple')
const command = `abc=123 barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} --variable=abc`
const command = `abc=123 npx barnard59 run --pipeline=http://example.org/pipeline/ --verbose ${pipelineFile} --variable=abc`

const result = stripAnsi(shell.exec(command, { silent: true, cwd }).stderr)

Expand All @@ -125,7 +125,7 @@ describe('barnard59', function () {
context(`${optionsBefore} run ${optionsAfter}`, () => {
it(title, () => {
const pipelineFile = filenamePipelineDefinition('simple')
const command = `${env} barnard59 ${optionsBefore} run --pipeline=http://example.org/pipeline/ -vv ${pipelineFile} ${optionsAfter}`
const command = `${env} npx barnard59 ${optionsBefore} run --pipeline=http://example.org/pipeline/ -vv ${pipelineFile} ${optionsAfter}`

const result = stripAnsi(shell.exec(command, { silent: true }).stderr)

Expand All @@ -138,34 +138,31 @@ describe('barnard59', function () {
})

describe('examples', function () {
// Examples can be a bit slow to run
this.timeout(5000)

it('should run the fetch-json-to-ntriples.json example without error', () => {
const pipelineFile = (new URL('../examples/fetch-json-to-ntriples.json', import.meta.url)).pathname
const command = `barnard59 run --pipeline=http://example.org/pipeline/cet ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/cet ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

strictEqual(result.code, 0)
strictEqual(result.code, 0, result.stderr)
})

it('should run the fetch-json-to-ntriples.ttl example without error', () => {
const pipelineFile = (new URL('../examples/fetch-json-to-ntriples.ttl', import.meta.url)).pathname
const command = `barnard59 run --pipeline=http://example.org/pipeline/utc ${pipelineFile}`
const command = `npx barnard59 run --pipeline=http://example.org/pipeline/utc ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

strictEqual(result.code, 0)
strictEqual(result.code, 0, result.stderr)
})

it('should run the parse-csvw.ttl example without error', () => {
const pipelineFile = (new URL('../examples/parse-csvw.ttl', import.meta.url)).pathname
const command = `barnard59 run -vv --pipeline=http://example.org/pipeline/parseCsvw ${pipelineFile}`
const command = `npx barnard59 run -vv --pipeline=http://example.org/pipeline/parseCsvw ${pipelineFile}`

const result = shell.exec(command, { silent: true, cwd })

strictEqual(result.code, 0)
strictEqual(result.code, 0, result.stderr)
})
})
})
2 changes: 1 addition & 1 deletion packages/graph-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"barnard59-core": "^6.0.1",
"barnard59-env": "^1.2.3",
"barnard59-test-support": "*",
"docker-compose": "^0.24.7",
"docker-compose": "^0.24.8",
"express-as-promise": "^1.2.0",
"get-stream": "^6.0.1",
"is-stream": "^3",
Expand Down
4 changes: 2 additions & 2 deletions packages/graph-store/test/pipeline.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { strictEqual } from 'node:assert'
import ParsingClient from 'sparql-http-client/ParsingClient.js'
import * as compose from 'docker-compose'
import { upAll } from 'docker-compose/dist/v2.js'
import waitOn from 'wait-on'
import { pipelineDefinitionLoader } from 'barnard59-test-support/loadPipelineDefinition.js'
import env from 'barnard59-env/index.ts'
Expand All @@ -20,7 +20,7 @@ const endpoint = 'http://localhost:3030/test'
describe('graph-store pipeline', function () {
before(async function () {
this.timeout(100000)
await compose.upAll({
await upAll({
cwd: support,
})
await waitOn({
Expand Down
1 change: 1 addition & 0 deletions packages/http/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.js
3 changes: 3 additions & 0 deletions packages/http/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.ts
!*.d.ts
test/
7 changes: 0 additions & 7 deletions packages/http/get.js

This file was deleted.

15 changes: 15 additions & 0 deletions packages/http/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { RequestInit } from 'node-fetch'
import type { GetInit } from './lib/fetch.js'
import fetch from './lib/fetch.js'

function get(options: GetInit): ReturnType<typeof fetch>
function get(url: string, options?: RequestInit): ReturnType<typeof fetch>
function get(urlOrOptions: GetInit | string, options: RequestInit = {}): ReturnType<typeof fetch> {
if (typeof urlOrOptions === 'string') {
return fetch({ ...options, url: urlOrOptions })
}

return fetch(urlOrOptions)
}

export default get
File renamed without changes.
12 changes: 7 additions & 5 deletions packages/http/lib/fetch.js → packages/http/lib/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { SpanStatusCode } from '@opentelemetry/api'
import toReadable from 'duplex-to/readable.js'
import type { RequestInit } from 'node-fetch'
import nodeFetch from 'node-fetch'
import tracer from './tracer.js'

async function fetch({ method = 'GET', url, ...options } = {}) {
export type GetInit = RequestInit & { url: string }

export default async function fetch({ method = 'GET', url, ...options }: GetInit) {
return await tracer.startActiveSpan('fetch', async span => {
try {
const response = await nodeFetch(url, { method, ...options })

return toReadable(response.body)
} catch (e) {
return toReadable(response.body as any)
} catch (e: any) {
span.recordException(e)
span.setStatus({ code: SpanStatusCode.ERROR, message: e.message })
} finally {
span.end()
}
})
}

export default fetch
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import duplexify from 'duplexify'
import nodeFetch from 'node-fetch'
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { Duplex } from 'node:stream'
import { PassThrough } from 'readable-stream'
import type { RequestInit } from 'node-fetch'
import nodeFetch from 'node-fetch'
import duplexify from 'duplexify'
import tracer from './tracer.js'

async function fetch({ method = 'POST', url, ...options } = {}) {
const inputStream = new PassThrough()
const outputStream = new PassThrough()
export type PostInit = RequestInit & { url: string }

export default async function writableFetch({ method = 'POST', url, ...options }: PostInit): Promise<Duplex> {
const inputStream: any = new PassThrough()
const outputStream: any = new PassThrough()

tracer.startActiveSpan('writableFetch', span => setTimeout(async () => {
try {
const response = await nodeFetch(url, { method, body: inputStream, ...options })

response.body.pipe(outputStream)
response.body!.pipe(outputStream)
} catch (err) {
outputStream.emit('error', err)
} finally {
Expand All @@ -21,5 +26,3 @@ async function fetch({ method = 'POST', url, ...options } = {}) {

return duplexify(inputStream, outputStream)
}

export default fetch
5 changes: 4 additions & 1 deletion packages/http/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"main": "index.js",
"type": "module",
"scripts": {
"test": "mocha"
"test": "mocha",
"build": "tsc",
"prepack": "npm run build"
},
"repository": {
"type": "git",
Expand All @@ -27,6 +29,7 @@
"readable-stream": ">=3"
},
"devDependencies": {
"@types/duplexify": "^3.6.4",
"express-as-promise": "^1.2.0",
"get-stream": "^6.0.1",
"is-stream": "^3.0.0"
Expand Down
7 changes: 0 additions & 7 deletions packages/http/post.js

This file was deleted.

15 changes: 15 additions & 0 deletions packages/http/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { RequestInit } from 'node-fetch'
import type { PostInit } from './lib/writableFetch.js'
import writableFetch from './lib/writableFetch.js'

function post(options: PostInit): ReturnType<typeof writableFetch>
function post(url: string, options: RequestInit): ReturnType<typeof writableFetch>
function post(urlOrOptions: PostInit | string, options: RequestInit = {}): ReturnType<typeof writableFetch> {
if (typeof urlOrOptions === 'string') {
return writableFetch({ ...options, url: urlOrOptions })
}

return writableFetch(urlOrOptions)
}

export default post
16 changes: 15 additions & 1 deletion packages/http/test/get.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { strictEqual } from 'assert'
import { strictEqual } from 'node:assert'
import withServer from 'express-as-promise/withServer.js'
import getStream from 'get-stream'
import { isReadableStream as isReadable, isWritableStream as isWritable } from 'is-stream'
Expand Down Expand Up @@ -32,4 +32,18 @@ describe('get', () => {
strictEqual(content, expected.content)
})
})

it('can be called with 2 arguments', async () => {
await withServer(async server => {
server.app.get('/', (req, res) => {
res.send(req.headers['x-test'])
})

const baseUrl = await server.listen()
const response = await get(baseUrl, { headers: { 'x-test': 'test header' } })
const content = await getStream(response)

strictEqual(content, 'test header')
})
})
})
Loading

0 comments on commit 6ff3428

Please sign in to comment.