diff --git a/.gitignore b/.gitignore index 3d7fc6ef..51ee0df3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ .DS_Store node_modules -esm +mjs cjs +types temp bun coverage diff --git a/biome.json b/biome.json index 10f04842..95c62eb9 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.2.4/schema.json", + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", "assist": { "actions": { "source": { diff --git a/cli/build.ts b/cli/build.ts new file mode 100644 index 00000000..1d52f7e7 --- /dev/null +++ b/cli/build.ts @@ -0,0 +1,78 @@ +import * as fs from "node:fs/promises"; +import { URL } from "node:url"; +import ts from "typescript"; +import { listFiles, listTsSourceStringLiterals } from "./util.ts"; + +interface OutputPattern { + destDir: URL; + /** @example .mjs, .cjs */ + ext: string; + compilerOptions: ts.CompilerOptions; +} + +const outputPattens = new Set(); +outputPattens.add({ + destDir: new URL("../mjs/", import.meta.url), + ext: ".mjs", + compilerOptions: { + target: ts.ScriptTarget.ESNext, + module: ts.ModuleKind.ESNext, + }, +}); +outputPattens.add({ + destDir: new URL("../cjs/", import.meta.url), + ext: ".cjs", + compilerOptions: { + target: ts.ScriptTarget.ESNext, + module: ts.ModuleKind.CommonJS, + }, +}); + +const srcDir = new URL("../src/", import.meta.url); +const exclude = [/\.test\..*$/]; +const baseTsConfig = JSON.parse( + await fs.readFile(new URL("../tsconfig.json", import.meta.url), "utf8"), +) as { compilerOptions: ts.CompilerOptions }; + +for await (const fileUrl of listFiles(srcDir, exclude)) { + const relativePath = fileUrl.pathname.slice(srcDir.pathname.length); + const filePath = fileUrl.pathname.slice(srcDir.pathname.length); + if (filePath.endsWith(".ts")) { + const tsCode = await fs.readFile(fileUrl, "utf-8"); + const tsSource = ts.createSourceFile( + filePath, + tsCode, + ts.ScriptTarget.ESNext, + ); + const replaceList: Array = []; + const ext = ".ts"; + for (const node of listTsSourceStringLiterals(tsSource)) { + const importFromText = node.text; + if (importFromText.startsWith(".") && importFromText.endsWith(ext)) { + replaceList.push(node); + } + } + replaceList.sort((n1, n2) => n2.getFullStart() - n1.getFullStart()); + for (const pattern of outputPattens) { + let code = tsCode; + for (const node of replaceList) { + const start = code.indexOf(node.text, node.getFullStart()); + const end = start + node.text.length; + code = `${code.slice(0, end - ext.length)}${pattern.ext}${code.slice(end)}`; + } + const output = ts.transpileModule(code, { + compilerOptions: { + ...baseTsConfig.compilerOptions, + ...pattern.compilerOptions, + }, + }); + const destUrl = new URL( + filePath.replace(/\.ts$/, pattern.ext), + pattern.destDir, + ); + await fs.mkdir(new URL(".", destUrl), { recursive: true }); + await fs.writeFile(destUrl, output.outputText); + } + console.info(`done:${relativePath}`); + } +} diff --git a/cli/temp.ts b/cli/temp.ts deleted file mode 100644 index 2daf3eb5..00000000 --- a/cli/temp.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as fs from "node:fs/promises"; -import { URL } from "node:url"; -import ts from "typescript"; -import { listFiles, listTsSourceStringLiterals } from "./util.ts"; - -const srcDir = new URL("../src/", import.meta.url); -const tempDir = new URL("../temp/", import.meta.url); -const exclude = [/\.test\..*$/]; - -await fs.mkdir(tempDir, { recursive: true }); - -for await (const fileUrl of listFiles(tempDir)) { - await fs.unlink(fileUrl); -} - -for await (const fileUrl of listFiles(srcDir, exclude)) { - const filePath = fileUrl.pathname.slice(srcDir.pathname.length); - if (filePath.endsWith(".ts")) { - let code = await fs.readFile(fileUrl, "utf-8"); - const tsSource = ts.createSourceFile( - filePath, - code, - ts.ScriptTarget.ESNext, - ); - const replaceList: Array = []; - const ext = ".ts"; - for (const node of listTsSourceStringLiterals(tsSource)) { - const importFromText = node.text; - if (importFromText.startsWith(".") && importFromText.endsWith(ext)) { - replaceList.push(node); - } - } - replaceList.sort((n1, n2) => n2.getFullStart() - n1.getFullStart()); - for (const node of replaceList) { - const start = code.indexOf(node.text, node.getFullStart()); - const end = start + node.text.length; - code = `${code.slice(0, end - ext.length)}.js${code.slice(end)}`; - } - const destUrl = new URL(filePath, tempDir); - await fs.mkdir(new URL(".", destUrl), { recursive: true }); - await fs.writeFile(destUrl, code); - } -} diff --git a/package-lock.json b/package-lock.json index 4e326df7..4164ea37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,16 +9,16 @@ "version": "3.0.1", "license": "Apache-2.0", "devDependencies": { - "@biomejs/biome": "2.2.4", - "@types/node": "24.5.2", + "@biomejs/biome": "2.2.5", + "@types/node": "24.7.2", "npm-run-all": "4.1.5", - "typescript": "5.9.2" + "typescript": "5.9.3" } }, "node_modules/@biomejs/biome": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.4.tgz", - "integrity": "sha512-TBHU5bUy/Ok6m8c0y3pZiuO/BZoY/OcGxoLlrfQof5s8ISVwbVBdFINPQZyFfKwil8XibYWb7JMwnT8wT4WVPg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.5.tgz", + "integrity": "sha512-zcIi+163Rc3HtyHbEO7CjeHq8DjQRs40HsGbW6vx2WI0tg8mYQOPouhvHSyEnCBAorfYNnKdR64/IxO7xQ5faw==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -32,20 +32,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.2.4", - "@biomejs/cli-darwin-x64": "2.2.4", - "@biomejs/cli-linux-arm64": "2.2.4", - "@biomejs/cli-linux-arm64-musl": "2.2.4", - "@biomejs/cli-linux-x64": "2.2.4", - "@biomejs/cli-linux-x64-musl": "2.2.4", - "@biomejs/cli-win32-arm64": "2.2.4", - "@biomejs/cli-win32-x64": "2.2.4" + "@biomejs/cli-darwin-arm64": "2.2.5", + "@biomejs/cli-darwin-x64": "2.2.5", + "@biomejs/cli-linux-arm64": "2.2.5", + "@biomejs/cli-linux-arm64-musl": "2.2.5", + "@biomejs/cli-linux-x64": "2.2.5", + "@biomejs/cli-linux-x64-musl": "2.2.5", + "@biomejs/cli-win32-arm64": "2.2.5", + "@biomejs/cli-win32-x64": "2.2.5" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.4.tgz", - "integrity": "sha512-RJe2uiyaloN4hne4d2+qVj3d3gFJFbmrr5PYtkkjei1O9c+BjGXgpUPVbi8Pl8syumhzJjFsSIYkcLt2VlVLMA==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.5.tgz", + "integrity": "sha512-MYT+nZ38wEIWVcL5xLyOhYQQ7nlWD0b/4mgATW2c8dvq7R4OQjt/XGXFkXrmtWmQofaIM14L7V8qIz/M+bx5QQ==", "cpu": [ "arm64" ], @@ -60,9 +60,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.4.tgz", - "integrity": "sha512-cFsdB4ePanVWfTnPVaUX+yr8qV8ifxjBKMkZwN7gKb20qXPxd/PmwqUH8mY5wnM9+U0QwM76CxFyBRJhC9tQwg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.5.tgz", + "integrity": "sha512-FLIEl73fv0R7dI10EnEiZLw+IMz3mWLnF95ASDI0kbx6DDLJjWxE5JxxBfmG+udz1hIDd3fr5wsuP7nwuTRdAg==", "cpu": [ "x64" ], @@ -77,9 +77,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.4.tgz", - "integrity": "sha512-M/Iz48p4NAzMXOuH+tsn5BvG/Jb07KOMTdSVwJpicmhN309BeEyRyQX+n1XDF0JVSlu28+hiTQ2L4rZPvu7nMw==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.5.tgz", + "integrity": "sha512-5DjiiDfHqGgR2MS9D+AZ8kOfrzTGqLKywn8hoXpXXlJXIECGQ32t+gt/uiS2XyGBM2XQhR6ztUvbjZWeccFMoQ==", "cpu": [ "arm64" ], @@ -94,9 +94,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.4.tgz", - "integrity": "sha512-7TNPkMQEWfjvJDaZRSkDCPT/2r5ESFPKx+TEev+I2BXDGIjfCZk2+b88FOhnJNHtksbOZv8ZWnxrA5gyTYhSsQ==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.5.tgz", + "integrity": "sha512-5Ov2wgAFwqDvQiESnu7b9ufD1faRa+40uwrohgBopeY84El2TnBDoMNXx6iuQdreoFGjwW8vH6k68G21EpNERw==", "cpu": [ "arm64" ], @@ -111,9 +111,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.4.tgz", - "integrity": "sha512-orr3nnf2Dpb2ssl6aihQtvcKtLySLta4E2UcXdp7+RTa7mfJjBgIsbS0B9GC8gVu0hjOu021aU8b3/I1tn+pVQ==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.5.tgz", + "integrity": "sha512-fq9meKm1AEXeAWan3uCg6XSP5ObA6F/Ovm89TwaMiy1DNIwdgxPkNwxlXJX8iM6oRbFysYeGnT0OG8diCWb9ew==", "cpu": [ "x64" ], @@ -128,9 +128,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.4.tgz", - "integrity": "sha512-m41nFDS0ksXK2gwXL6W6yZTYPMH0LughqbsxInSKetoH6morVj43szqKx79Iudkp8WRT5SxSh7qVb8KCUiewGg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.5.tgz", + "integrity": "sha512-AVqLCDb/6K7aPNIcxHaTQj01sl1m989CJIQFQEaiQkGr2EQwyOpaATJ473h+nXDUuAcREhccfRpe/tu+0wu0eQ==", "cpu": [ "x64" ], @@ -145,9 +145,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.4.tgz", - "integrity": "sha512-NXnfTeKHDFUWfxAefa57DiGmu9VyKi0cDqFpdI+1hJWQjGJhJutHPX0b5m+eXvTKOaf+brU+P0JrQAZMb5yYaQ==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.5.tgz", + "integrity": "sha512-xaOIad4wBambwJa6mdp1FigYSIF9i7PCqRbvBqtIi9y29QtPVQ13sDGtUnsRoe6SjL10auMzQ6YAe+B3RpZXVg==", "cpu": [ "arm64" ], @@ -162,9 +162,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.4.tgz", - "integrity": "sha512-3Y4V4zVRarVh/B/eSHczR4LYoSVyv3Dfuvm3cWs5w/HScccS0+Wt/lHOcDTRYeHjQmMYVC3rIRWqyN2EI52+zg==", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.5.tgz", + "integrity": "sha512-F/jhuXCssPFAuciMhHKk00xnCAxJRS/pUzVfXYmOMUp//XW7mO6QeCjsjvnm8L4AO/dG2VOB0O+fJPiJ2uXtIw==", "cpu": [ "x64" ], @@ -179,13 +179,13 @@ } }, "node_modules/@types/node": { - "version": "24.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz", - "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==", + "version": "24.7.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.2.tgz", + "integrity": "sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.12.0" + "undici-types": "~7.14.0" } }, "node_modules/array-buffer-byte-length": { @@ -1376,9 +1376,9 @@ } }, "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1405,9 +1405,9 @@ } }, "node_modules/undici-types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", - "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index b4d5a8d1..ae33af78 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,17 @@ "homepage": "https://github.com/nlibjs/typing", "repository": "https://github.com/nlibjs/typing", "type": "module", - "main": "./esm/mod.js", "exports": { - "import": "./esm/mod.js", - "require": "./cjs/mod.js" + "./package.json": "./package.json", + ".": { + "import": "./mjs/mod.js", + "require": "./cjs/mod.js", + "types": "./types/mod.d.ts" + } }, "files": [ "cjs", - "esm", + "mjs", "!**/*.test.*" ], "scripts": { @@ -36,9 +39,8 @@ "lint": "biome check", "build": "run-s build:*", "build:index": "node cli/generate-index.ts", - "build:temp": "node cli/temp.ts", - "build:esm": "tsc --project tsconfig.esm.json", - "build:cjs": "tsc --project tsconfig.cjs.json", + "build:types": "tsc", + "build:code": "node cli/build.ts", "version": "run-s version:*", "version:changelog": "npx @nlib/changelog --output CHANGELOG.md", "version:add-changelog": "git add CHANGELOG.md", @@ -46,10 +48,10 @@ "version:add-jsr": "git add jsr.json" }, "devDependencies": { - "@biomejs/biome": "2.2.4", - "@types/node": "24.5.2", + "@biomejs/biome": "2.2.5", + "@types/node": "24.7.2", "npm-run-all": "4.1.5", - "typescript": "5.9.2" + "typescript": "5.9.3" }, "renovate": { "extends": [ diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json deleted file mode 100644 index 2cfb9b61..00000000 --- a/tsconfig.cjs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "CommonJS", - "moduleResolution": "Node", - "outDir": "cjs", - "noEmit": false, - "allowImportingTsExtensions": false - }, - "include": ["./temp/**/*.ts"], - "exclude": ["**/*.test.*"] -} diff --git a/tsconfig.esm.json b/tsconfig.esm.json deleted file mode 100644 index 006b2c26..00000000 --- a/tsconfig.esm.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "NodeNext", - "moduleResolution": "NodeNext", - "outDir": "esm", - "noEmit": false, - "allowImportingTsExtensions": false - }, - "include": ["./temp/**/*.ts"], - "exclude": ["**/*.test.*"] -} diff --git a/tsconfig.json b/tsconfig.json index e3f8e447..bc2ddeaa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,8 +11,9 @@ "noImplicitReturns": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noEmit": true, - "allowImportingTsExtensions": true + "allowImportingTsExtensions": true, + "emitDeclarationOnly": true, + "outDir": "./types" }, "include": ["./src/**/*.ts"] } diff --git a/tsconfig.types.json b/tsconfig.types.json new file mode 100644 index 00000000..c2040835 --- /dev/null +++ b/tsconfig.types.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "outDir": "./types" + }, + "exclude": ["**/*.test.*"] +}