From 52c1ab42bbf9414bc0d9c423c61f7a3df0c190f7 Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Wed, 6 Nov 2024 13:51:52 +0000 Subject: [PATCH 1/7] feat(build): for both exports to be the same --- build/build.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/build/build.ts b/build/build.ts index ac8ae6f27..8586cf31e 100644 --- a/build/build.ts +++ b/build/build.ts @@ -7,14 +7,14 @@ /// -import fs, { write } from 'fs' -import path from 'path' import arg from 'arg' +import { $, stdout } from 'bun' import { build } from 'esbuild' import type { Plugin, PluginBuild, BuildOptions } from 'esbuild' import * as glob from 'glob' +import fs from 'fs' +import path from 'path' import { removePrivateFields } from './remove-private-fields' -import { $, stdout } from 'bun' const args = arg({ '--watch': Boolean, @@ -26,6 +26,24 @@ const entryPoints = glob.sync('./src/**/*.ts', { ignore: ['./src/**/*.test.ts', './src/mod.ts', './src/middleware.ts', './src/deno/**/*.ts'], }) +const readJsonExports = (path: string) => JSON.parse(fs.readFileSync(path, 'utf-8')).exports + +const [packageJsonExports, jsrJsonExports] = ['./package.json', './jsr.json'].map(readJsonExports) + +const validateEntries = ( + source: Record, + target: Record, + fileName: string +) => + Object.keys(source).forEach((entry) => { + if (!(entry in target)) { + throw new Error(`Missing ${entry} in ${fileName}`) + } + }) + +validateEntries(packageJsonExports, jsrJsonExports, 'jsr.json') +validateEntries(jsrJsonExports, packageJsonExports, 'package.json') + /* This plugin is inspired by the following. https://github.com/evanw/esbuild/issues/622#issuecomment-769462611 From ddcf4e6cfb4be7606054b4915cfd0e50233beee9 Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 03:37:02 +0000 Subject: [PATCH 2/7] some fix --- build/build.ts | 41 ++++++++++++++++++++++++++++++++++------- jsr.json | 1 + package.json | 8 ++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/build/build.ts b/build/build.ts index 8586cf31e..99fda7810 100644 --- a/build/build.ts +++ b/build/build.ts @@ -30,19 +30,46 @@ const readJsonExports = (path: string) => JSON.parse(fs.readFileSync(path, 'utf- const [packageJsonExports, jsrJsonExports] = ['./package.json', './jsr.json'].map(readJsonExports) -const validateEntries = ( +const validateExports = ( source: Record, target: Record, fileName: string -) => - Object.keys(source).forEach((entry) => { - if (!(entry in target)) { - throw new Error(`Missing ${entry} in ${fileName}`) +) => { + const isEntryInTarget = (entry: string): boolean => { + if (entry in target) { + return true + } + + // e.g., "./utils/*" -> "./utils" + const wildcardPrefix = entry.replace(/\/\*$/, '') + if (entry.endsWith('/*')) { + return Object.keys(target).some( + (targetEntry) => + targetEntry.startsWith(wildcardPrefix + '/') && targetEntry !== wildcardPrefix + ) + } + + const separatedEntry = entry.split('/') + while (separatedEntry.length > 0) { + const pattern = `${separatedEntry.join('/')}/*` + if (pattern in target) { + return true + } + separatedEntry.pop() + } + + return false + } + + Object.keys(source).forEach((sourceEntry) => { + if (!isEntryInTarget(sourceEntry)) { + throw new Error(`Missing ${sourceEntry} in ${fileName}`) } }) +} -validateEntries(packageJsonExports, jsrJsonExports, 'jsr.json') -validateEntries(jsrJsonExports, packageJsonExports, 'package.json') +validateExports(packageJsonExports, jsrJsonExports, 'jsr.json') +validateExports(jsrJsonExports, packageJsonExports, 'package.json') /* This plugin is inspired by the following. diff --git a/jsr.json b/jsr.json index 1beea8916..aecc6083f 100644 --- a/jsr.json +++ b/jsr.json @@ -80,6 +80,7 @@ "./testing": "./src/helper/testing/index.ts", "./dev": "./src/helper/dev/index.ts", "./ws": "./src/helper/websocket/index.ts", + "./conninfo": "./src/helper/conninfo/index.ts", "./utils/body": "./src/utils/body.ts", "./utils/buffer": "./src/utils/buffer.ts", "./utils/color": "./src/utils/color.ts", diff --git a/package.json b/package.json index 3cd048ac7..47aca6fb8 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,11 @@ "import": "./dist/index.js", "require": "./dist/cjs/index.js" }, + "./request": { + "types": "./dist/types/request.d.ts", + "import": "./dist/request.js", + "require": "./dist/cjs/request.js" + }, "./types": { "types": "./dist/types/types.d.ts", "import": "./dist/types.js", @@ -387,6 +392,9 @@ }, "typesVersions": { "*": { + "request": [ + "./dist/types/request" + ], "types": [ "./dist/types/types" ], From 13ad404a0bb53cadeaf43b956d66a97f6daa58bc Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 03:45:50 +0000 Subject: [PATCH 3/7] fix exclude of coverage --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index 33898853b..92c2d6e35 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -20,7 +20,7 @@ export default defineConfig({ ...(configDefaults.coverage.exclude ?? []), 'benchmarks', 'runtime-tests', - 'build.ts', + 'build/build.ts', 'src/test-utils', 'perf-measures', From 945f5495f9319a615dffa6070c3be4c270382db8 Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 06:58:14 +0000 Subject: [PATCH 4/7] update --- build/build.ts | 47 +++-------------------------- build/remove-private-fields.test.ts | 4 +-- build/validate-exports.test.ts | 31 +++++++++++++++++++ build/validate-exports.ts | 37 +++++++++++++++++++++++ vitest.config.ts | 2 +- 5 files changed, 76 insertions(+), 45 deletions(-) create mode 100644 build/validate-exports.test.ts create mode 100644 build/validate-exports.ts diff --git a/build/build.ts b/build/build.ts index 99fda7810..293743dad 100644 --- a/build/build.ts +++ b/build/build.ts @@ -15,6 +15,7 @@ import * as glob from 'glob' import fs from 'fs' import path from 'path' import { removePrivateFields } from './remove-private-fields' +import { validateExports } from './validate-exports' const args = arg({ '--watch': Boolean, @@ -22,55 +23,17 @@ const args = arg({ const isWatch = args['--watch'] || false -const entryPoints = glob.sync('./src/**/*.ts', { - ignore: ['./src/**/*.test.ts', './src/mod.ts', './src/middleware.ts', './src/deno/**/*.ts'], -}) - const readJsonExports = (path: string) => JSON.parse(fs.readFileSync(path, 'utf-8')).exports const [packageJsonExports, jsrJsonExports] = ['./package.json', './jsr.json'].map(readJsonExports) -const validateExports = ( - source: Record, - target: Record, - fileName: string -) => { - const isEntryInTarget = (entry: string): boolean => { - if (entry in target) { - return true - } - - // e.g., "./utils/*" -> "./utils" - const wildcardPrefix = entry.replace(/\/\*$/, '') - if (entry.endsWith('/*')) { - return Object.keys(target).some( - (targetEntry) => - targetEntry.startsWith(wildcardPrefix + '/') && targetEntry !== wildcardPrefix - ) - } - - const separatedEntry = entry.split('/') - while (separatedEntry.length > 0) { - const pattern = `${separatedEntry.join('/')}/*` - if (pattern in target) { - return true - } - separatedEntry.pop() - } - - return false - } - - Object.keys(source).forEach((sourceEntry) => { - if (!isEntryInTarget(sourceEntry)) { - throw new Error(`Missing ${sourceEntry} in ${fileName}`) - } - }) -} - validateExports(packageJsonExports, jsrJsonExports, 'jsr.json') validateExports(jsrJsonExports, packageJsonExports, 'package.json') +const entryPoints = glob.sync('./src/**/*.ts', { + ignore: ['./src/**/*.test.ts', './src/mod.ts', './src/middleware.ts', './src/deno/**/*.ts'], +}) + /* This plugin is inspired by the following. https://github.com/evanw/esbuild/issues/622#issuecomment-769462611 diff --git a/build/remove-private-fields.test.ts b/build/remove-private-fields.test.ts index b2ec3d729..ecbb2d638 100644 --- a/build/remove-private-fields.test.ts +++ b/build/remove-private-fields.test.ts @@ -1,9 +1,9 @@ /// -import { removePrivateFields } from './remove-private-fields' import fs from 'node:fs/promises' -import path from 'node:path' import os from 'node:os' +import path from 'node:path' +import { removePrivateFields } from './remove-private-fields' describe('removePrivateFields', () => { it('Works', async () => { diff --git a/build/validate-exports.test.ts b/build/validate-exports.test.ts new file mode 100644 index 000000000..f00607c3f --- /dev/null +++ b/build/validate-exports.test.ts @@ -0,0 +1,31 @@ +/// + +import { validateExports } from './validate-exports' + +const mockExports1 = { + './a': './a.ts', + './b': './b.ts', + './c/a': './c.ts', + './d/*': './d/*.ts', +} + +const mockExports2 = { + './a': './a.ts', + './b': './b.ts', + './c/a': './c.ts', + './d/a': './d/a.ts', +} + +const mockExports3 = { + './a': './a.ts', + './c/a': './c.ts', + './d/*': './d/*.ts', +} + +describe('validateExports', () => { + it('Works', async () => { + expect(() => validateExports(mockExports1, mockExports1, 'package.json')).not.toThrowError() + expect(() => validateExports(mockExports1, mockExports2, 'jsr.json')).not.toThrowError() + expect(() => validateExports(mockExports1, mockExports3, 'package.json')).toThrowError() + }) +}) diff --git a/build/validate-exports.ts b/build/validate-exports.ts new file mode 100644 index 000000000..951853525 --- /dev/null +++ b/build/validate-exports.ts @@ -0,0 +1,37 @@ +export const validateExports = ( + source: Record, + target: Record, + fileName: string +) => { + const isEntryInTarget = (entry: string): boolean => { + if (entry in target) { + return true + } + + // e.g., "./utils/*" -> "./utils" + const wildcardPrefix = entry.replace(/\/\*$/, '') + if (entry.endsWith('/*')) { + return Object.keys(target).some( + (targetEntry) => + targetEntry.startsWith(wildcardPrefix + '/') && targetEntry !== wildcardPrefix + ) + } + + const separatedEntry = entry.split('/') + while (separatedEntry.length > 0) { + const pattern = `${separatedEntry.join('/')}/*` + if (pattern in target) { + return true + } + separatedEntry.pop() + } + + return false + } + + Object.keys(source).forEach((sourceEntry) => { + if (!isEntryInTarget(sourceEntry)) { + throw new Error(`Missing ${sourceEntry} in ${fileName}`) + } + }) +} diff --git a/vitest.config.ts b/vitest.config.ts index 92c2d6e35..55c8b58b7 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ }, test: { globals: true, - include: ['**/src/**/(*.)+(spec|test).+(ts|tsx|js)', '**/scripts/**/(*.)+(spec|test).+(ts|tsx|js)'], + include: ['**/src/**/(*.)+(spec|test).+(ts|tsx|js)', '**/scripts/**/(*.)+(spec|test).+(ts|tsx|js)', '**/build/**/(*.)+(spec|test).+(ts|tsx|js)'], exclude: [...configDefaults.exclude, '**/sandbox/**', '**/*.case.test.+(ts|tsx|js)'], setupFiles: ['./.vitest.config/setup-vitest.ts'], coverage: { From fbd1265a68fcd68b7bb8d82be7ac820152edd262 Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 07:04:52 +0000 Subject: [PATCH 5/7] stylish error message and add comment --- build/build.ts | 1 + build/validate-exports.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build/build.ts b/build/build.ts index 293743dad..34285bb7c 100644 --- a/build/build.ts +++ b/build/build.ts @@ -27,6 +27,7 @@ const readJsonExports = (path: string) => JSON.parse(fs.readFileSync(path, 'utf- const [packageJsonExports, jsrJsonExports] = ['./package.json', './jsr.json'].map(readJsonExports) +// Validate exports of package.json and jsr.json validateExports(packageJsonExports, jsrJsonExports, 'jsr.json') validateExports(jsrJsonExports, packageJsonExports, 'package.json') diff --git a/build/validate-exports.ts b/build/validate-exports.ts index 951853525..6fabf9a09 100644 --- a/build/validate-exports.ts +++ b/build/validate-exports.ts @@ -31,7 +31,7 @@ export const validateExports = ( Object.keys(source).forEach((sourceEntry) => { if (!isEntryInTarget(sourceEntry)) { - throw new Error(`Missing ${sourceEntry} in ${fileName}`) + throw new Error(`Missing "${sourceEntry}" in '${fileName}'`) } }) } From b754cee3536c4f2e0d80bbb3f8fe477e16dec12d Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 07:43:00 +0000 Subject: [PATCH 6/7] revert auto lint --- build/remove-private-fields.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/remove-private-fields.test.ts b/build/remove-private-fields.test.ts index ecbb2d638..2ffa852fb 100644 --- a/build/remove-private-fields.test.ts +++ b/build/remove-private-fields.test.ts @@ -1,9 +1,9 @@ /// +import { removePrivateFields } from './remove-private-fields' import fs from 'node:fs/promises' -import os from 'node:os' import path from 'node:path' -import { removePrivateFields } from './remove-private-fields' +import os from 'node:os' describe('removePrivateFields', () => { it('Works', async () => { @@ -18,4 +18,4 @@ describe('removePrivateFields', () => { it('Should throw error when path does not exist', () => { expect(() => removePrivateFields('./unknown.ts')).toThrowError(Error) }) -}) +}) \ No newline at end of file From efa95f0be2d219b22edbf96b3bb34d32ad921338 Mon Sep 17 00:00:00 2001 From: Ame_x Edam Date: Thu, 7 Nov 2024 07:45:28 +0000 Subject: [PATCH 7/7] chore: format --- build/remove-private-fields.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/remove-private-fields.test.ts b/build/remove-private-fields.test.ts index 2ffa852fb..b2ec3d729 100644 --- a/build/remove-private-fields.test.ts +++ b/build/remove-private-fields.test.ts @@ -18,4 +18,4 @@ describe('removePrivateFields', () => { it('Should throw error when path does not exist', () => { expect(() => removePrivateFields('./unknown.ts')).toThrowError(Error) }) -}) \ No newline at end of file +})