diff --git a/.changeset/fix-exports-minor.md b/.changeset/fix-exports-minor.md new file mode 100644 index 0000000..0b2458d --- /dev/null +++ b/.changeset/fix-exports-minor.md @@ -0,0 +1,13 @@ +--- +"@aokiapp/tlv": minor +--- + +Expand public API: expose parser schema types to consumers. + +Changes: +- Add public exports for parser schema types to support direct typing in user code. +- Update tests to use package-level path aliases resolved by Vite plugin and tests/tsconfig.json. +- Enhance test runner script to compile declarations for tests before running Vitest. +- Update Vitest config for path alias resolution and coverage improvements; remove 'dist' from coverage exclude. + +No runtime behavior changes; semver-minor due to expanded public API surface. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 671491e..f8e2faa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@aokiapp/tlv", - "version": "0.2.1", + "version": "0.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@aokiapp/tlv", - "version": "0.2.1", + "version": "0.3.1", "license": "SEE LICENSE IN LICENSE.md", "devDependencies": { "@changesets/cli": "^2.29.5", @@ -18,6 +18,7 @@ "rimraf": "^5.0.5", "typescript": "^5.8.3", "typescript-eslint": "^8.29.0", + "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.1.1" } }, @@ -3317,6 +3318,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4750,6 +4758,27 @@ "typescript": ">=4.8.4" } }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4959,6 +4988,26 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-tsconfig-paths": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", + "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/vite/node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", diff --git a/package.json b/package.json index 408fe93..65a8194 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "typecheck": "tsc --noEmit", "lint": "eslint .", "format": "prettier --write .", - "test": "vitest run", + "test": "tsc -p tests/tsconfig.json --emitDeclarationOnly && vitest run", "prepack": "npm run build", "changelog": "changeset", "version": "changeset version", @@ -69,6 +69,7 @@ "rimraf": "^5.0.5", "typescript": "^5.8.3", "typescript-eslint": "^8.29.0", + "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.1.1" } -} \ No newline at end of file +} diff --git a/src/parser/schema-parser.ts b/src/parser/schema-parser.ts index eff3d32..9b9dfdc 100644 --- a/src/parser/schema-parser.ts +++ b/src/parser/schema-parser.ts @@ -17,7 +17,7 @@ type OptionalFlag = { /** * Base interface for a TLV schema object. */ -interface TLVSchemaBase { +export interface TLVSchemaBase { readonly name: N; readonly tagClass: TagClass; readonly tagNumber: number; @@ -31,7 +31,7 @@ interface TLVSchemaBase { * Interface for defining a primitive TLV schema. * @template DecodedType - The type after decoding. */ -interface PrimitiveTLVSchema< +export interface PrimitiveTLVSchema< N extends string = string, DecodedType = DefaultDecodeType, > extends TLVSchemaBase { @@ -46,7 +46,7 @@ interface PrimitiveTLVSchema< * Interface for defining a constructed TLV schema. * @template F - The array of child field schemas. */ -interface ConstructedTLVSchema< +export interface ConstructedTLVSchema< N extends string = string, F extends readonly TLVSchema[] = readonly TLVSchema[], > extends TLVSchemaBase { @@ -55,14 +55,14 @@ interface ConstructedTLVSchema< } // Describes a repeated TLV schema entry (e.g. SET/SEQUENCE OF). -interface RepeatedTLVSchema< +export interface RepeatedTLVSchema< N extends string = string, Item extends TLVSchema = TLVSchema, > extends TLVSchemaBase { readonly item: Item; } -type TLVSchema = +export type TLVSchema = | PrimitiveTLVSchema | ConstructedTLVSchema | RepeatedTLVSchema; diff --git a/tests/fixtures/schemas.ts b/tests/fixtures/schemas.ts index fc1da61..dc3a32a 100644 --- a/tests/fixtures/schemas.ts +++ b/tests/fixtures/schemas.ts @@ -1,4 +1,4 @@ -import { Schema, TagClass } from "../../src/parser"; +import { Schema, TagClass } from "@aokiapp/tlv/parser"; import { decodeOffsets, decodePublicKey, decodeText } from "../helpers/utils"; export const schemaCertificate = Schema.constructed( diff --git a/tests/helpers/utils.ts b/tests/helpers/utils.ts index 81c9ae4..abdce77 100644 --- a/tests/helpers/utils.ts +++ b/tests/helpers/utils.ts @@ -1,4 +1,4 @@ -import { BasicTLVParser } from "../../src/parser"; +import { BasicTLVParser } from "@aokiapp/tlv/parser"; function arrayBufferToBase64url(buffer: ArrayBuffer): string { if (typeof Buffer !== "undefined") { diff --git a/tests/integration/schema/roundtrip.test.ts b/tests/integration/schema/roundtrip.test.ts index fb1416b..9be1c24 100644 --- a/tests/integration/schema/roundtrip.test.ts +++ b/tests/integration/schema/roundtrip.test.ts @@ -1,10 +1,10 @@ // tests/integration/schema/roundtrip.test.ts import { describe, it } from "vitest"; import assert from "assert"; -import { Schema as BSchema, SchemaBuilder } from "../../../src/builder"; -import { Schema as PSchema, SchemaParser } from "../../../src/parser"; -import { TagClass } from "../../../src/common/types"; -import { toHex } from "../../../src/common/codecs"; +import { Schema as BSchema, SchemaBuilder } from "@aokiapp/tlv/builder"; +import { Schema as PSchema, SchemaParser } from "@aokiapp/tlv/parser"; +import { TagClass } from "@aokiapp/tlv/common"; +import { toHex } from "@aokiapp/tlv/common"; import { fromHexString } from "../../helpers/utils"; describe("Integration: constructed build→parse round-trip preserves data shape", () => { diff --git a/tests/schema.ts b/tests/schema.ts index 836b9ba..8fbd568 100644 --- a/tests/schema.ts +++ b/tests/schema.ts @@ -1,4 +1,4 @@ -import { Schema, TagClass } from "../src/parser"; +import { Schema, TagClass } from "@aokiapp/tlv/parser"; import { decodeOffsets, decodePublicKey, decodeText } from "./utils"; export const schemaCertificate = Schema.constructed( diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..3ee22d7 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "esnext", + "moduleResolution": "bundler", + "declaration": true, + "noEmit": true, + "strict": false, + "skipLibCheck": true, + "baseUrl": ".", + "paths": { + "@aokiapp/tlv": ["../src/index.ts"], + "@aokiapp/tlv/parser": ["../src/parser/index.ts"], + "@aokiapp/tlv/builder": ["../src/builder/index.ts"], + "@aokiapp/tlv/common": ["../src/common/index.ts"] + } + }, + "include": ["**/*.ts"] +} diff --git a/tests/types/build.types.test.ts b/tests/types/build.types.test.ts index 3e5305d..c8ef374 100644 --- a/tests/types/build.types.test.ts +++ b/tests/types/build.types.test.ts @@ -1,6 +1,6 @@ // tests/types/build.types.test.ts import { describe, it } from "vitest"; -import { Schema as BSchema, SchemaBuilder } from "../../src/builder"; +import { Schema as BSchema, SchemaBuilder } from "@aokiapp/tlv/builder"; import { AssertTypeCompatible, assertTypeTrue } from "../helpers/utils"; describe("build-only type test (single large constructed schema)", () => { diff --git a/tests/types/parse.types.test.ts b/tests/types/parse.types.test.ts index 06def7d..2f487bd 100644 --- a/tests/types/parse.types.test.ts +++ b/tests/types/parse.types.test.ts @@ -1,6 +1,6 @@ // tests/types/parse.types.test.ts import { describe, it } from "vitest"; -import { Schema as PSchema, SchemaParser } from "../../src/parser"; +import { Schema as PSchema, SchemaParser } from "@aokiapp/tlv/parser"; import { AssertTypeCompatible, assertTypeTrue } from "../helpers/utils"; describe("parse-only type test (single large constructed schema)", () => { diff --git a/tests/unit/common/codecs.test.ts b/tests/unit/common/codecs.test.ts index 1a05a7f..675cf83 100644 --- a/tests/unit/common/codecs.test.ts +++ b/tests/unit/common/codecs.test.ts @@ -15,7 +15,7 @@ import { decodeOID, decodeBitStringHex, encodeBitString, -} from "../../../src/common/codecs"; +} from "@aokiapp/tlv/common"; describe("codecs: buffer and hex helpers", () => { it("bufferToArrayBuffer converts Buffer to ArrayBuffer", () => { diff --git a/tests/unit/schema/builder.core.test.ts b/tests/unit/schema/builder.core.test.ts index 1cd585b..5ce47d9 100644 --- a/tests/unit/schema/builder.core.test.ts +++ b/tests/unit/schema/builder.core.test.ts @@ -5,9 +5,9 @@ import { Schema as BSchema, SchemaBuilder, BasicTLVBuilder, -} from "../../../src/builder"; -import { TagClass } from "../../../src/common/types"; -import { identity, toHex } from "../../../src/common/codecs"; +} from "@aokiapp/tlv/builder"; +import { TagClass } from "@aokiapp/tlv/common"; +import { identity, toHex } from "@aokiapp/tlv/common"; function toHexBuf(buf: ArrayBuffer): string { return toHex(new Uint8Array(buf)); diff --git a/tests/unit/schema/parser.additional-coverage.test.ts b/tests/unit/schema/parser.additional-coverage.test.ts index a92e90e..3cc9d80 100644 --- a/tests/unit/schema/parser.additional-coverage.test.ts +++ b/tests/unit/schema/parser.additional-coverage.test.ts @@ -1,9 +1,9 @@ // tests/unit/schema/parser.additional-coverage.test.ts import { describe, it, expect } from "vitest"; import assert from "assert"; -import { Schema as PSchema, SchemaParser } from "../../../src/parser"; +import { Schema as PSchema, SchemaParser } from "@aokiapp/tlv/parser"; import { fromHexString } from "../../helpers/utils"; -import { identity } from "../../../src/common"; +import { identity } from "@aokiapp/tlv/common"; describe("SEQUENCE: tail optional skip when content ends", () => { it("skips trailing optional field at end-of-content", () => { diff --git a/tests/unit/schema/parser.sequence-set.test.ts b/tests/unit/schema/parser.sequence-set.test.ts index a298102..853c42c 100644 --- a/tests/unit/schema/parser.sequence-set.test.ts +++ b/tests/unit/schema/parser.sequence-set.test.ts @@ -5,8 +5,8 @@ import { Schema as PSchema, SchemaParser, BasicTLVParser, -} from "../../../src/parser"; -import { TagClass } from "../../../src/common/types"; +} from "@aokiapp/tlv/parser"; +import { TagClass } from "@aokiapp/tlv/common"; import { fromHexString } from "../../helpers/utils"; describe("SchemaParser primitive: trailing bytes strict gating", () => { diff --git a/tests/unit/tlv/basic-tlv.length-exceed.test.ts b/tests/unit/tlv/basic-tlv.length-exceed.test.ts index 293e3ed..3db8ff3 100644 --- a/tests/unit/tlv/basic-tlv.length-exceed.test.ts +++ b/tests/unit/tlv/basic-tlv.length-exceed.test.ts @@ -1,7 +1,7 @@ // tests/unit/tlv/basic-tlv.length-exceed.test.ts import { describe, it } from "vitest"; import assert from "assert"; -import { BasicTLVParser } from "../../../src/parser"; +import { BasicTLVParser } from "@aokiapp/tlv/parser"; import { fromHexString } from "../../helpers/utils"; describe("BasicTLVParser.readValue: declared length exceeds available bytes", () => { diff --git a/tests/unit/tlv/basic-tlv.test.ts b/tests/unit/tlv/basic-tlv.test.ts index aff36fe..ce30139 100644 --- a/tests/unit/tlv/basic-tlv.test.ts +++ b/tests/unit/tlv/basic-tlv.test.ts @@ -1,10 +1,10 @@ // tests/unit/tlv/basic-tlv.test.ts import { describe, it } from "vitest"; import assert from "assert"; -import { BasicTLVParser } from "../../../src/parser"; -import { TagClass } from "../../../src/common/types"; -import { BasicTLVBuilder } from "../../../src/builder"; -import { toHex } from "../../../src/common/codecs"; +import { BasicTLVParser } from "@aokiapp/tlv/parser"; +import { TagClass } from "@aokiapp/tlv/common"; +import { BasicTLVBuilder } from "@aokiapp/tlv/builder"; +import { toHex } from "@aokiapp/tlv/common"; import { fromHexString } from "../../helpers/utils"; describe("BasicTLVParser: length and tag-number forms", () => { diff --git a/tests/utils.ts b/tests/utils.ts index 00c3f25..abdce77 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,4 +1,4 @@ -import { BasicTLVParser } from "../src/parser"; +import { BasicTLVParser } from "@aokiapp/tlv/parser"; function arrayBufferToBase64url(buffer: ArrayBuffer): string { if (typeof Buffer !== "undefined") { diff --git a/vitest.config.js b/vitest.config.js index d1a2b08..038978e 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -1,11 +1,29 @@ import { defineConfig } from "vitest/config"; +import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ + // Resolve @aokiapp/tlv/* via tests/tsconfig.json without changing test imports + plugins: [ + tsconfigPaths({ + projects: ["./tests/tsconfig.json"], + }), + ], test: { globals: true, environment: "node", include: ["tests/**/*.test.ts"], exclude: ["tests/_migrated/**"], + // Inline the package entrypoints so Vite transforms & instruments source for coverage + server: { + deps: { + inline: [ + "@aokiapp/tlv", + "@aokiapp/tlv/parser", + "@aokiapp/tlv/builder", + "@aokiapp/tlv/common", + ], + }, + }, coverage: { enabled: true, provider: "istanbul", @@ -14,7 +32,6 @@ export default defineConfig({ exclude: [ "tests/**", "examples/**", - "dist/**", ".changeset/**", "**/*.d.ts", ],