diff --git a/.gitignore b/.gitignore
index d8e3c8d..4eb4fb3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,8 @@ dist/
node_modules/
coverage/
.typeforge/
-.openapi-codegen/
test/fixtures/layouts/
*.tsbuildinfo
.tmp/
typeforge.local.json
-openapi-codegen.local.json
.env
diff --git a/README.md b/README.md
index d8d5942..279ba7a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
# @openmirai/typeforge
@@ -11,10 +11,6 @@ Headless **OpenAPI / Swagger → TypeScript** codegen. The CLI is `typeforge`. I
You own `http.ts` (the `HTTPFetch` adapter). Generated files import that adapter — they do not invent axios/fetch calls inline.
-## Migrating from `@openmirai/openapi-codegen`
-
-Install `@openmirai/typeforge` and update package imports and scripts to use the canonical `typeforge` name. During migration, the package also exposes the legacy `openapi-codegen` binary and reads `openapi-codegen.json`, `openapi-codegen.local.json`, and the `openapiCodegen` package.json key. New projects created by `typeforge init` use the Typeforge names.
-
## What it generates
For each **source** (a named API, e.g. `atlas`), under `//generated/`:
diff --git a/docs/cli.md b/docs/cli.md
index 5513e32..62c7c3c 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -2,8 +2,6 @@
Install `@openmirai/typeforge` from [npmjs](https://www.npmjs.com/package/@openmirai/typeforge). Add a script so the binary resolves from `node_modules/.bin`:
-The legacy `openapi-codegen` binary and configuration filenames remain readable during migration, but all new usage should use `typeforge`.
-
```json
{
"scripts": {
diff --git a/package.json b/package.json
index 8a6b42f..72538bb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@openmirai/typeforge",
- "version": "0.1.8",
+ "version": "0.2.0",
"description": "Typeforge: headless OpenAPI to TypeScript codegen CLI and HTTPFetch runtime",
"homepage": "https://github.com/openmirai/typeforge#readme",
"bugs": {
@@ -12,11 +12,9 @@
"url": "git+https://github.com/openmirai/typeforge.git"
},
"bin": {
- "openapi-codegen": "./dist/cli.js",
"typeforge": "./dist/cli.js"
},
"files": [
- "assets/typeforge-logo.png",
"dist"
],
"type": "module",
@@ -59,6 +57,7 @@
},
"scripts": {
"build": "tsdown",
+ "check:package": "node scripts/check-package.mjs",
"typecheck": "tsc -p tsconfig.json --pretty false && tsc -p tsconfig.tools.json --pretty false",
"format": "oxfmt --check .",
"format:fix": "oxfmt --write .",
@@ -69,7 +68,7 @@
"test:coverage": "vitest run --coverage",
"prepare": "husky",
"release": "release-it",
- "verify": "pnpm format && pnpm lint && pnpm typecheck && pnpm build && pnpm test:coverage"
+ "verify": "pnpm format && pnpm lint && pnpm typecheck && pnpm build && pnpm check:package && pnpm test:coverage"
},
"dependencies": {
"chalk": "5.6.2"
diff --git a/scripts/check-package.mjs b/scripts/check-package.mjs
new file mode 100644
index 0000000..874c279
--- /dev/null
+++ b/scripts/check-package.mjs
@@ -0,0 +1,47 @@
+import { execFileSync } from "node:child_process";
+
+const output = execFileSync(
+ "npm",
+ ["pack", "--dry-run", "--json", "--ignore-scripts"],
+ { encoding: "utf8" }
+);
+const [pack] = JSON.parse(output);
+
+if (pack === undefined) {
+ throw new Error("npm pack did not return package metadata");
+}
+
+const paths = pack.files.map((file) => file.path);
+const unexpected = paths.filter(
+ (path) =>
+ path !== "README.md" && path !== "package.json" && !path.startsWith("dist/")
+);
+const sourceMaps = paths.filter((path) => path.endsWith(".map"));
+
+if (unexpected.length > 0) {
+ throw new Error(`Unexpected package files: ${unexpected.join(", ")}`);
+}
+if (sourceMaps.length > 0) {
+ throw new Error(
+ `Source maps must not be published: ${sourceMaps.join(", ")}`
+ );
+}
+if (pack.entryCount > 20) {
+ throw new Error(
+ `Package contains ${pack.entryCount} files; expected at most 20`
+ );
+}
+if (pack.size > 75_000) {
+ throw new Error(
+ `Package tarball is ${pack.size} bytes; expected at most 75000`
+ );
+}
+if (pack.unpackedSize > 125_000) {
+ throw new Error(
+ `Package is ${pack.unpackedSize} unpacked bytes; expected at most 125000`
+ );
+}
+
+process.stdout.write(
+ `typeforge package: ${pack.size} packed bytes, ${pack.unpackedSize} unpacked bytes, ${pack.entryCount} files\n`
+);
diff --git a/src/config/__tests__/load.test.ts b/src/config/__tests__/load.test.ts
index 7a95317..ffb98ce 100644
--- a/src/config/__tests__/load.test.ts
+++ b/src/config/__tests__/load.test.ts
@@ -15,7 +15,7 @@ function sortedStrings(values: Array): Array {
}
describe("config/load", () => {
- it("prefers typeforge.json over legacy and package config", () => {
+ it("prefers typeforge.json over package config", () => {
const cwd = join(
process.cwd(),
"test/fixtures/layouts",
@@ -27,11 +27,6 @@ describe("config/load", () => {
JSON.stringify({ apiRoot: "packages/utils/src/api" }),
"utf8"
);
- writeFileSync(
- join(cwd, "openapi-codegen.json"),
- JSON.stringify({ apiRoot: "legacy" }),
- "utf8"
- );
writeFileSync(
join(cwd, "package.json"),
JSON.stringify({ typeforge: { apiRoot: "ignored" } }),
@@ -41,34 +36,6 @@ describe("config/load", () => {
expect(loadProjectConfig(cwd).apiRoot).toBe("packages/utils/src/api");
});
- it("reads legacy project config during migration", () => {
- const jsonCwd = join(
- process.cwd(),
- "test/fixtures/layouts",
- `config-legacy-json-${Date.now()}`
- );
- mkdirSync(jsonCwd, { recursive: true });
- writeFileSync(
- join(jsonCwd, "openapi-codegen.json"),
- JSON.stringify({ apiRoot: "legacy/json" }),
- "utf8"
- );
- expect(loadProjectConfig(jsonCwd).apiRoot).toBe("legacy/json");
-
- const packageCwd = join(
- process.cwd(),
- "test/fixtures/layouts",
- `config-legacy-package-${Date.now()}`
- );
- mkdirSync(packageCwd, { recursive: true });
- writeFileSync(
- join(packageCwd, "package.json"),
- JSON.stringify({ openapiCodegen: { apiRoot: "legacy/package" } }),
- "utf8"
- );
- expect(loadProjectConfig(packageCwd).apiRoot).toBe("legacy/package");
- });
-
it("parses source.ts config fields", () => {
const cwd = join(
process.cwd(),
diff --git a/src/config/load.ts b/src/config/load.ts
index 0e4b657..44e329d 100644
--- a/src/config/load.ts
+++ b/src/config/load.ts
@@ -33,7 +33,7 @@ function readPackageConfig(path: string): TypeforgeConfig {
try {
const raw = readJsonObject(readFileSync(path, "utf8"));
- const typeforge = raw["typeforge"] ?? raw["openapiCodegen"];
+ const typeforge = raw["typeforge"];
if (
typeof typeforge !== "object" ||
typeforge === null ||
@@ -201,15 +201,10 @@ function parseQueryExtends(content: string): QueryExtendsConfig | undefined {
export function loadProjectConfig(cwd: string): TypeforgeConfig {
const fromJson = readOptionalJson(resolve(cwd, "typeforge.json"));
- const fromLegacyJson = readOptionalJson(resolve(cwd, "openapi-codegen.json"));
const fromPackage = readPackageConfig(resolve(cwd, "package.json"));
return {
- apiRoot:
- fromJson.apiRoot ??
- fromLegacyJson.apiRoot ??
- fromPackage.apiRoot ??
- DEFAULT_API_ROOT,
+ apiRoot: fromJson.apiRoot ?? fromPackage.apiRoot ?? DEFAULT_API_ROOT,
};
}
diff --git a/src/config/types.ts b/src/config/types.ts
index 3757bb0..76890c1 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -2,9 +2,6 @@ export interface TypeforgeConfig {
apiRoot?: string;
}
-/** @deprecated Use `TypeforgeConfig`. */
-export type OpenApiCodegenConfig = TypeforgeConfig;
-
export type GenerationMode = "authoritative" | "merge";
export type NamingStrategy = "path" | "operationId";
diff --git a/src/index.ts b/src/index.ts
index 5d686bc..37a41ff 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -34,7 +34,6 @@ export { defineSourceConfig } from "./config/define";
export type {
GenerationMode,
NamingStrategy,
- OpenApiCodegenConfig,
TypeforgeConfig,
QueryExtendsConfig,
SourceConfig,
diff --git a/src/init/index.ts b/src/init/index.ts
index 6f422e7..0720655 100644
--- a/src/init/index.ts
+++ b/src/init/index.ts
@@ -156,12 +156,10 @@ export function initProject(options: InitOptions): {
const cwd = options.cwd ?? process.cwd();
const layout = options.layout ?? "monolith";
const configPath = resolve(cwd, "typeforge.json");
- const legacyConfigPath = resolve(cwd, "openapi-codegen.json");
const projectConfig = loadProjectConfig(cwd);
- const apiRoot =
- existsSync(configPath) || existsSync(legacyConfigPath)
- ? (projectConfig.apiRoot ?? DEFAULT_API_ROOT)
- : defaultApiRoot(layout);
+ const apiRoot = existsSync(configPath)
+ ? (projectConfig.apiRoot ?? DEFAULT_API_ROOT)
+ : defaultApiRoot(layout);
const apiRootPath = resolve(cwd, apiRoot);
const sourceDir = join(apiRootPath, options.sourceKey);
@@ -200,7 +198,7 @@ export function initProject(options: InitOptions): {
}
const configWritePath = resolve(cwd, "typeforge.json");
- if (!existsSync(configWritePath) && !existsSync(legacyConfigPath)) {
+ if (!existsSync(configWritePath)) {
const config: TypeforgeConfig = { apiRoot };
writeFileSync(
configWritePath,
diff --git a/src/parser/loader.ts b/src/parser/loader.ts
index 38b1c13..0ec4302 100644
--- a/src/parser/loader.ts
+++ b/src/parser/loader.ts
@@ -74,13 +74,7 @@ export function resolveSpecSource(
}
// 4. Local override file
- const defaultLocalPath = "./typeforge.local.json";
- const legacyLocalPath = "./openapi-codegen.local.json";
- const localPath =
- opts.localOverridePath ??
- (existsSync(defaultLocalPath) || !existsSync(legacyLocalPath)
- ? defaultLocalPath
- : legacyLocalPath);
+ const localPath = opts.localOverridePath ?? "./typeforge.local.json";
if (existsSync(localPath)) {
try {
const localData = readJsonObject(readFileSync(localPath, "utf8")),
diff --git a/test/e2e/cli.test.ts b/test/e2e/cli.test.ts
index f52b331..9948fce 100644
--- a/test/e2e/cli.test.ts
+++ b/test/e2e/cli.test.ts
@@ -79,29 +79,6 @@ describe("e2e cli init", () => {
"// keep me"
);
});
-
- it("uses legacy project config without writing a duplicate", () => {
- const root = join(fixtureRoot, "layouts", `cli-init-legacy-${Date.now()}`);
- tempRoots.push(root);
- mkdirSync(root, { recursive: true });
- writeFileSync(
- join(root, "openapi-codegen.json"),
- JSON.stringify({ apiRoot: "legacy/api" }),
- "utf8"
- );
-
- const result = runCli(root, [
- "init",
- "--source",
- "atlas",
- "--client",
- "fetch",
- ]);
-
- expect(result.exitCode).toBe(0);
- expect(existsSync(join(root, "legacy/api/http.ts"))).toBe(true);
- expect(existsSync(join(root, "typeforge.json"))).toBe(false);
- });
});
describe("e2e cli generate", () => {
diff --git a/tsdown.config.ts b/tsdown.config.ts
index 42bd404..df88198 100644
--- a/tsdown.config.ts
+++ b/tsdown.config.ts
@@ -4,13 +4,12 @@ const shared = {
deps: {
neverBundle: true,
},
- dts: {
- sourcemap: true,
- },
+ dts: true,
fixedExtension: false,
format: "esm",
+ minify: true,
outDir: "dist",
- sourcemap: true,
+ sourcemap: false,
target: "es2022",
treeshake: true,
tsconfig: "tsconfig.json",