From e372ff0e8523257b1ca004f969186918b15532f8 Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Wed, 15 Jan 2025 15:35:55 +0000 Subject: [PATCH 1/6] build(dependabot): reduce npm updates to monthly (#44) --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index dfa7fa6..35d66ca 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,5 +9,5 @@ updates: - package-ecosystem: "npm" directory: "/" schedule: - interval: "weekly" + interval: "monthly" open-pull-requests-limit: 10 From f9657fd0b248df71d33922b7b3e0bd1082e0a5b9 Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Mon, 3 Feb 2025 09:14:08 +0000 Subject: [PATCH 2/6] chore: rename master to main (#45) --- .github/workflows/ci.yml | 1 - .github/workflows/package-manager-ci.yml | 1 - README.md | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2c109e..4722e78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - master - next - 'v*' paths-ignore: diff --git a/.github/workflows/package-manager-ci.yml b/.github/workflows/package-manager-ci.yml index 1ea2c6d..c34af86 100644 --- a/.github/workflows/package-manager-ci.yml +++ b/.github/workflows/package-manager-ci.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - master - next - 'v*' paths-ignore: diff --git a/README.md b/README.md index 0a4eaaa..e613e0e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![NPM version](https://img.shields.io/npm/v/fast-content-type-parse.svg?style=flat)](https://www.npmjs.com/package/fast-content-type-parse) [![NPM downloads](https://img.shields.io/npm/dm/fast-content-type-parse.svg?style=flat)](https://www.npmjs.com/package/fast-content-type-parse) -[![CI](https://github.com/fastify/fast-content-type-parse/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/fastify/fast-content-type-parse/actions/workflows/ci.yml) +[![CI](https://github.com/fastify/fast-content-type-parse/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fast-content-type-parse/actions/workflows/ci.yml) [![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard) [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/fastify/.github/blob/main/SECURITY.md) From c2cde20bbd0000813668e8a99b8bc98072bf416d Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Sun, 2 Mar 2025 10:30:18 +0100 Subject: [PATCH 3/6] ci: drop node18 (#47) --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4722e78..496e8b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,4 +20,3 @@ jobs: with: license-check: true lint: true - node-versions: '["16", "18", "20", "22"]' From d98fc41b1d3e1a6aad97a8c4d4cd4fbb06c2f028 Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Fri, 7 Mar 2025 19:19:13 +0000 Subject: [PATCH 4/6] ci(ci): set job permissions (#48) --- .github/workflows/ci.yml | 3 +++ .github/workflows/package-manager-ci.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 496e8b9..f9fae55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,9 @@ on: jobs: test: + permissions: + contents: write + pull-requests: write uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5 with: license-check: true diff --git a/.github/workflows/package-manager-ci.yml b/.github/workflows/package-manager-ci.yml index c34af86..c6d598e 100644 --- a/.github/workflows/package-manager-ci.yml +++ b/.github/workflows/package-manager-ci.yml @@ -16,4 +16,6 @@ on: jobs: test: + permissions: + contents: read uses: fastify/workflows/.github/workflows/plugins-ci-package-manager.yml@v5 From 2b05ca2304ca0747ba1ccb1d1083bb471b2b323c Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Sat, 8 Mar 2025 09:27:05 +0100 Subject: [PATCH 5/6] chore: migrate to node test runner (#46) --- package.json | 4 +- test/index.test.js | 166 ++++++++++++++++++++++----------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/package.json b/package.json index c090df9..66a5742 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lint:fix": "eslint --fix", "test": "npm run test:unit && npm run test:typescript", "test:typescript": "tsd", - "test:unit": "tap" + "test:unit": "c8 --100 node --test" }, "keywords": [ "content-type", @@ -61,10 +61,10 @@ "@fastify/pre-commit": "^2.1.0", "benchmark": "^2.1.4", "busboy": "^1.6.0", + "c8": "^10.1.3", "content-type": "^1.0.4", "eslint": "^9.17.0", "neostandard": "^0.12.0", - "tap": "^19.2.5", "tsd": "^0.31.0" }, "pre-commit": [ diff --git a/test/index.test.js b/test/index.test.js index 5c5932b..ecc314f 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,6 +1,6 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const { parse, safeParse } = require('..') const invalidTypes = [ @@ -17,232 +17,232 @@ const invalidTypes = [ 'text/plain,wrong' ] -test('parse', function (t) { +test('parse', async function (t) { t.plan(13 + invalidTypes.length) - t.test('should parse basic type', function (t) { + await t.test('should parse basic type', function (t) { t.plan(1) const type = parse('text/html') - t.strictSame(type.type, 'text/html') + t.assert.deepStrictEqual(type.type, 'text/html') }) - t.test('should parse with suffix', function (t) { + await t.test('should parse with suffix', function (t) { t.plan(1) const type = parse('image/svg+xml') - t.strictSame(type.type, 'image/svg+xml') + t.assert.deepStrictEqual(type.type, 'image/svg+xml') }) - t.test('should parse basic type with surrounding OWS', function (t) { + await t.test('should parse basic type with surrounding OWS', function (t) { t.plan(1) const type = parse(' text/html ') - t.strictSame(type.type, 'text/html') + t.assert.deepStrictEqual(type.type, 'text/html') }) - t.test('should parse parameters', function (t) { + await t.test('should parse parameters', function (t) { t.plan(2) const type = parse('text/html; charset=utf-8; foo=bar') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'utf-8', foo: 'bar' }) }) - t.test('should parse parameters with extra LWS', function (t) { + await t.test('should parse parameters with extra LWS', function (t) { t.plan(2) const type = parse('text/html ; charset=utf-8 ; foo=bar') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'utf-8', foo: 'bar' }) }) - t.test('should lower-case type', function (t) { + await t.test('should lower-case type', function (t) { t.plan(1) const type = parse('IMAGE/SVG+XML') - t.strictSame(type.type, 'image/svg+xml') + t.assert.deepStrictEqual(type.type, 'image/svg+xml') }) - t.test('should lower-case parameter names', function (t) { + await t.test('should lower-case parameter names', function (t) { t.plan(2) const type = parse('text/html; Charset=UTF-8') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-8' }) }) - t.test('should unquote parameter values', function (t) { + await t.test('should unquote parameter values', function (t) { t.plan(2) const type = parse('text/html; charset="UTF-8"') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-8' }) }) - t.test('should unquote parameter values with escapes', function (t) { + await t.test('should unquote parameter values with escapes', function (t) { t.plan(2) const type = parse('text/html; charset="UT\\F-\\\\\\"8\\""') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-\\"8"' }) }) - t.test('should handle balanced quotes', function (t) { + await t.test('should handle balanced quotes', function (t) { t.plan(2) const type = parse('text/html; param="charset=\\"utf-8\\"; foo=bar"; bar=foo') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { param: 'charset="utf-8"; foo=bar', bar: 'foo' }) }) - invalidTypes.forEach(function (type) { - t.test('should throw on invalid media type ' + type, function (t) { + invalidTypes.forEach(async function (type) { + await t.test('should throw on invalid media type ' + type, function (t) { t.plan(1) - t.throws(parse.bind(null, type), 'invalid media type') + t.assert.throws(parse.bind(null, type), new TypeError('invalid media type')) }) }) - t.test('should throw on invalid parameter format', function (t) { + await t.test('should throw on invalid parameter format', function (t) { t.plan(3) - t.throws(parse.bind(null, 'text/plain; foo="bar'), 'invalid parameter format') - t.throws(parse.bind(null, 'text/plain; profile=http://localhost; foo=bar'), 'invalid parameter format') - t.throws(parse.bind(null, 'text/plain; profile=http://localhost'), 'invalid parameter format') + t.assert.throws(parse.bind(null, 'text/plain; foo="bar'), new TypeError('invalid parameter format')) + t.assert.throws(parse.bind(null, 'text/plain; profile=http://localhost; foo=bar'), new TypeError('invalid parameter format')) + t.assert.throws(parse.bind(null, 'text/plain; profile=http://localhost'), new TypeError('invalid parameter format')) }) - t.test('should require argument', function (t) { + await t.test('should require argument', function (t) { t.plan(1) // @ts-expect-error should reject non-strings - t.throws(parse.bind(null), 'argument header is required and must be a string') + t.assert.throws(parse.bind(null), new TypeError('argument header is required and must be a string')) }) - t.test('should reject non-strings', function (t) { + await t.test('should reject non-strings', function (t) { t.plan(1) // @ts-expect-error should reject non-strings - t.throws(parse.bind(null, 7), 'argument header is required and must be a string') + t.assert.throws(parse.bind(null, 7), new TypeError('argument header is required and must be a string')) }) }) -test('safeParse', function (t) { +test('safeParse', async function (t) { t.plan(13 + invalidTypes.length) - t.test('should safeParse basic type', function (t) { + await t.test('should safeParse basic type', function (t) { t.plan(1) const type = safeParse('text/html') - t.strictSame(type.type, 'text/html') + t.assert.deepStrictEqual(type.type, 'text/html') }) - t.test('should safeParse with suffix', function (t) { + await t.test('should safeParse with suffix', function (t) { t.plan(1) const type = safeParse('image/svg+xml') - t.strictSame(type.type, 'image/svg+xml') + t.assert.deepStrictEqual(type.type, 'image/svg+xml') }) - t.test('should safeParse basic type with surrounding OWS', function (t) { + await t.test('should safeParse basic type with surrounding OWS', function (t) { t.plan(1) const type = safeParse(' text/html ') - t.strictSame(type.type, 'text/html') + t.assert.deepStrictEqual(type.type, 'text/html') }) - t.test('should safeParse parameters', function (t) { + await t.test('should safeParse parameters', function (t) { t.plan(2) const type = safeParse('text/html; charset=utf-8; foo=bar') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'utf-8', foo: 'bar' }) }) - t.test('should safeParse parameters with extra LWS', function (t) { + await t.test('should safeParse parameters with extra LWS', function (t) { t.plan(2) const type = safeParse('text/html ; charset=utf-8 ; foo=bar') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'utf-8', foo: 'bar' }) }) - t.test('should lower-case type', function (t) { + await t.test('should lower-case type', function (t) { t.plan(1) const type = safeParse('IMAGE/SVG+XML') - t.strictSame(type.type, 'image/svg+xml') + t.assert.deepStrictEqual(type.type, 'image/svg+xml') }) - t.test('should lower-case parameter names', function (t) { + await t.test('should lower-case parameter names', function (t) { t.plan(2) const type = safeParse('text/html; Charset=UTF-8') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-8' }) }) - t.test('should unquote parameter values', function (t) { + await t.test('should unquote parameter values', function (t) { t.plan(2) const type = safeParse('text/html; charset="UTF-8"') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-8' }) }) - t.test('should unquote parameter values with escapes', function (t) { + await t.test('should unquote parameter values with escapes', function (t) { t.plan(2) const type = safeParse('text/html; charset="UT\\F-\\\\\\"8\\""') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { charset: 'UTF-\\"8"' }) }) - t.test('should handle balanced quotes', function (t) { + await t.test('should handle balanced quotes', function (t) { t.plan(2) const type = safeParse('text/html; param="charset=\\"utf-8\\"; foo=bar"; bar=foo') - t.strictSame(type.type, 'text/html') - t.same(type.parameters, { + t.assert.deepStrictEqual(type.type, 'text/html') + t.assert.deepEqual(type.parameters, { param: 'charset="utf-8"; foo=bar', bar: 'foo' }) }) - invalidTypes.forEach(function (type) { - t.test('should return dummyContentType on invalid media type ' + type, function (t) { + invalidTypes.forEach(async function (type) { + await t.test('should return dummyContentType on invalid media type ' + type, function (t) { t.plan(2) - t.equal(safeParse(type).type, '') - t.equal(Object.keys(safeParse(type).parameters).length, 0) + t.assert.deepStrictEqual(safeParse(type).type, '') + t.assert.deepStrictEqual(Object.keys(safeParse(type).parameters).length, 0) }) }) - t.test('should return dummyContentType on invalid parameter format', function (t) { + await t.test('should return dummyContentType on invalid parameter format', function (t) { t.plan(6) - t.equal(safeParse('text/plain; foo="bar').type, '') - t.equal(Object.keys(safeParse('text/plain; foo="bar').parameters).length, 0) + t.assert.deepStrictEqual(safeParse('text/plain; foo="bar').type, '') + t.assert.deepStrictEqual(Object.keys(safeParse('text/plain; foo="bar').parameters).length, 0) - t.equal(safeParse('text/plain; profile=http://localhost; foo=bar').type, '') - t.equal(Object.keys(safeParse('text/plain; profile=http://localhost; foo=bar').parameters).length, 0) + t.assert.deepStrictEqual(safeParse('text/plain; profile=http://localhost; foo=bar').type, '') + t.assert.deepStrictEqual(Object.keys(safeParse('text/plain; profile=http://localhost; foo=bar').parameters).length, 0) - t.equal(safeParse('text/plain; profile=http://localhost').type, '') - t.equal(Object.keys(safeParse('text/plain; profile=http://localhost').parameters).length, 0) + t.assert.deepStrictEqual(safeParse('text/plain; profile=http://localhost').type, '') + t.assert.deepStrictEqual(Object.keys(safeParse('text/plain; profile=http://localhost').parameters).length, 0) }) - t.test('should return dummyContentType on missing argument', function (t) { + await t.test('should return dummyContentType on missing argument', function (t) { t.plan(2) // @ts-expect-error should reject non-strings - t.equal(safeParse().type, '') + t.assert.deepStrictEqual(safeParse().type, '') // @ts-expect-error should reject non-strings - t.equal(Object.keys(safeParse().parameters).length, 0) + t.assert.deepStrictEqual(Object.keys(safeParse().parameters).length, 0) }) - t.test('should return dummyContentType on non-strings', function (t) { + await t.test('should return dummyContentType on non-strings', function (t) { t.plan(2) // @ts-expect-error should reject non-strings - t.equal(safeParse(null).type, '') + t.assert.deepStrictEqual(safeParse(null).type, '') // @ts-expect-error should reject non-strings - t.equal(Object.keys(safeParse(null).parameters).length, 0) + t.assert.deepStrictEqual(Object.keys(safeParse(null).parameters).length, 0) }) }) From bf6861c1a2bad438f9a1f274477096aff04a09fd Mon Sep 17 00:00:00 2001 From: Frazer Smith Date: Sat, 8 Mar 2025 16:32:48 +0000 Subject: [PATCH 6/6] 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66a5742..52c9f99 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fast-content-type-parse", - "version": "2.0.1", + "version": "3.0.0", "description": "Parse HTTP Content-Type header according to RFC 7231", "main": "index.js", "type": "commonjs",