From a6ccfa29cac213a9c30aed0c2b8a8607fb8a9aaa Mon Sep 17 00:00:00 2001 From: EdamAmex <121654029+EdamAme-x@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:37:53 +0900 Subject: [PATCH] chore(build): validate if exporting is correct in `package.json` and `jsr.json` (#3638) * feat(build): for both exports to be the same * some fix * fix exclude of coverage * update * stylish error message and add comment * revert auto lint * chore: format --- build/build.ts | 15 +++++++++++--- build/validate-exports.test.ts | 31 ++++++++++++++++++++++++++++ build/validate-exports.ts | 37 ++++++++++++++++++++++++++++++++++ jsr.json | 1 + package.json | 8 ++++++++ vitest.config.ts | 4 ++-- 6 files changed, 91 insertions(+), 5 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 ac8ae6f2..34285bb7 100644 --- a/build/build.ts +++ b/build/build.ts @@ -7,14 +7,15 @@ /// -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' +import { validateExports } from './validate-exports' const args = arg({ '--watch': Boolean, @@ -22,6 +23,14 @@ const args = arg({ const isWatch = args['--watch'] || false +const readJsonExports = (path: string) => JSON.parse(fs.readFileSync(path, 'utf-8')).exports + +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') + const entryPoints = glob.sync('./src/**/*.ts', { ignore: ['./src/**/*.test.ts', './src/mod.ts', './src/middleware.ts', './src/deno/**/*.ts'], }) diff --git a/build/validate-exports.test.ts b/build/validate-exports.test.ts new file mode 100644 index 00000000..f00607c3 --- /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 00000000..6fabf9a0 --- /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/jsr.json b/jsr.json index 1beea891..aecc6083 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 3cd048ac..47aca6fb 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" ], diff --git a/vitest.config.ts b/vitest.config.ts index 33898853..55c8b58b 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: { @@ -20,7 +20,7 @@ export default defineConfig({ ...(configDefaults.coverage.exclude ?? []), 'benchmarks', 'runtime-tests', - 'build.ts', + 'build/build.ts', 'src/test-utils', 'perf-measures',