Skip to content

Commit 9e4ea12

Browse files
authored
Merge pull request #36 from poviolabs/feature/file-config
Add file config & Update lint
2 parents 7a3612f + 1dc7be9 commit 9e4ea12

91 files changed

Lines changed: 925 additions & 473 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
{
22
"parser": "@typescript-eslint/parser",
3-
"plugins": ["@typescript-eslint", "prettier"],
3+
"plugins": ["@typescript-eslint", "prettier", "no-relative-import-paths"],
44
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
55
"parserOptions": {
6-
"project": "./tsconfig.json"
6+
"project": "./tsconfig.eslint.json"
77
},
88
"root": true,
99
"env": {
10-
"node": true,
11-
"jest": true
10+
"node": true
1211
},
1312
"rules": {
14-
"@typescript-eslint/interface-name-prefix": "off",
15-
"no-console": 0,
16-
"@typescript-eslint/ban-ts-comment": [0],
13+
"no-console": ["error"],
1714
"prettier/prettier": [
1815
"error",
1916
{
2017
"endOfLine": "auto"
2118
}
2219
],
23-
"@typescript-eslint/no-explicit-any": 0,
24-
"@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }]
20+
"@typescript-eslint/no-explicit-any": ["error"],
21+
"@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }],
22+
"no-relative-import-paths/no-relative-import-paths": ["error", { "allowSameFolder": true }]
2523
}
2624
}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ node_modules
1717

1818
# Test specs
1919
test/*
20-
!config/petstore.yaml
20+
!test/petstore.yaml
21+
!test/config.ts

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,45 @@ yarn openapi-codegen generate --input http://localhost:3001/docs-json
2424
yarn openapi-codegen generate --input http://localhost:3001/docs-json --standalone
2525
```
2626

27+
## Configuration Files
28+
29+
The CLI supports TypeScript configuration files to simplify command execution and provide consistent settings with full type safety. Configuration files are automatically discovered in your project root.
30+
31+
**Note:** Command-line arguments always take precedence over configuration file values, allowing you to override specific settings when needed.
32+
33+
### Quick Start
34+
35+
Create an `openapi-codegen.config.ts` file:
36+
37+
```typescript
38+
import { OpenAPICodegenConfig } from "@povio/openapi-codegen-cli";
39+
40+
const config: OpenAPICodegenConfig = {
41+
input: "http://localhost:4000/docs-json/",
42+
output: "src/data",
43+
};
44+
45+
export default config;
46+
```
47+
48+
Then run without arguments:
49+
50+
```bash
51+
yarn openapi-codegen generate
52+
```
53+
54+
### Configuration File Discovery
55+
56+
The CLI automatically searches for the TypeScript configuration file:
57+
58+
- `openapi-codegen.config.ts`
59+
60+
You can also specify a custom configuration file:
61+
62+
```bash
63+
yarn openapi-codegen generate --config my-config.ts
64+
```
65+
2766
## Options
2867

2968
#### Generate command (generates Zod schemas, API definitions and React queries)

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@povio/openapi-codegen-cli",
3-
"version": "0.14.9",
3+
"version": "0.15.0",
44
"main": "./dist/index.js",
55
"bin": {
66
"openapi-codegen": "./dist/sh.js"
@@ -12,14 +12,13 @@
1212
"build:clean": "rm -rf ./dist",
1313
"build:types": "tsc --project . --declaration --emitDeclarationOnly",
1414
"build": "yarn build:clean && yarn build:types && node ./esbuild.mjs && chmod +x ./dist/sh.js",
15-
"build:check": "yarn tsc --project . --noEmit",
1615
"start:dist": "node ./dist/sh.js",
1716
"typecheck": "tsc --noEmit",
18-
"lint": "eslint --fix",
19-
"format:check": "prettier --check .",
20-
"format:fix": "prettier --write .",
17+
"lint": "eslint ./src",
18+
"check": "yarn typecheck && yarn lint && yarn test",
2119
"push": "yarn exec ./scripts/publish.sh",
22-
"dev:generate": "rm -rf ./output && yarn start generate --input ./test/test.json"
20+
"dev:generate": "rm -rf ./output && yarn start generate --config ./test/config.ts",
21+
"dev:check": "yarn start check --config ./test/config.ts"
2322
},
2423
"files": [
2524
"dist/*",
@@ -53,6 +52,7 @@
5352
"esbuild": "^0.21.3",
5453
"eslint": "^8.57.0",
5554
"eslint-config-prettier": "^9.1.0",
55+
"eslint-plugin-no-relative-import-paths": "^1.6.1",
5656
"eslint-plugin-prettier": "^5.1.3",
5757
"handlebars": "^4.7.8",
5858
"openapi-types": "^12.1.3",

src/commands/check.command.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
1-
import { DEFAULT_GENERATE_OPTIONS } from "src/generators/const/options.const";
21
import yargs from "yargs";
3-
import { logBanner, logVariable } from "../helpers/cli.helper";
4-
import { getVersion } from "../helpers/version.helper";
5-
import { getBuilder, YargOption } from "../helpers/yargs.helper";
2+
import { logBanner } from "src/helpers/cli.helper";
3+
import { getVersion } from "src/helpers/version.helper";
4+
import { getBuilder, YargOption } from "src/helpers/yargs.helper";
65
import { check, CheckParams } from "./check";
76

87
class CheckOptions implements CheckParams {
9-
@YargOption({ envAlias: "input", demandOption: true })
10-
input!: string;
8+
@YargOption({ envAlias: "config" })
9+
config?: string;
1110

12-
@YargOption({ envAlias: "splitByTags", default: DEFAULT_GENERATE_OPTIONS.splitByTags, type: "boolean" })
13-
splitByTags!: boolean;
11+
@YargOption({ envAlias: "input" })
12+
input?: string;
1413

15-
@YargOption({ envAlias: "defaultTag", default: DEFAULT_GENERATE_OPTIONS.defaultTag })
16-
defaultTag!: string;
14+
@YargOption({ envAlias: "splitByTags", type: "boolean" })
15+
splitByTags?: boolean;
1716

18-
@YargOption({ envAlias: "excludeTags", default: DEFAULT_GENERATE_OPTIONS.excludeTags.join(",") })
19-
excludeTags!: string;
17+
@YargOption({ envAlias: "defaultTag" })
18+
defaultTag?: string;
2019

21-
@YargOption({ envAlias: "excludePathRegex", default: DEFAULT_GENERATE_OPTIONS.excludePathRegex })
22-
excludePathRegex!: string;
20+
@YargOption({ envAlias: "excludeTags" })
21+
excludeTags?: string;
2322

24-
@YargOption({
25-
envAlias: "excludeRedundantZodSchemas",
26-
default: DEFAULT_GENERATE_OPTIONS.excludeRedundantZodSchemas,
27-
type: "boolean",
28-
})
29-
excludeRedundantZodSchemas!: boolean;
23+
@YargOption({ envAlias: "excludePathRegex" })
24+
excludePathRegex?: string;
25+
26+
@YargOption({ envAlias: "excludeRedundantZodSchemas", type: "boolean" })
27+
excludeRedundantZodSchemas?: boolean;
3028

3129
@YargOption({ envAlias: "verbose", default: false, type: "boolean" })
32-
verbose!: boolean;
30+
verbose?: boolean;
3331
}
3432

3533
export const command: yargs.CommandModule = {
@@ -40,7 +38,6 @@ export const command: yargs.CommandModule = {
4038
const argv = (await _argv) as unknown as CheckOptions;
4139
if (argv.verbose) {
4240
logBanner(`OpenAPI CodeGen ${getVersion()}`);
43-
logVariable("input", argv.input);
4441
}
4542
return check(argv);
4643
},

src/commands/check.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
11
import SwaggerParser from "@apidevtools/swagger-parser";
22
import { OpenAPIV3 } from "openapi-types";
33
import { checkOpenAPIDoc } from "src/generators/checkOpenAPIDoc";
4+
import { DEFAULT_GENERATE_OPTIONS } from "src/generators/const/options.const";
45
import { GenerateOptions } from "src/generators/types/options";
6+
import { deepMerge } from "src/generators/utils/object.utils";
57
import { logInfo, logSuccess } from "src/helpers/cli.helper";
8+
import { loadConfig } from "src/helpers/config.helper";
69

710
export type CheckParams = {
8-
excludeTags: string;
9-
verbose: boolean;
10-
} & Pick<GenerateOptions, "input" | "splitByTags" | "defaultTag">;
11+
config?: string;
12+
excludeTags?: string;
13+
verbose?: boolean;
14+
} & Partial<Pick<GenerateOptions, "input" | "splitByTags" | "defaultTag">>;
1115

12-
export async function check({ input, excludeTags, verbose, ...params }: CheckParams) {
16+
export async function check({ verbose, ...params }: CheckParams) {
1317
const start = Date.now();
1418

1519
if (verbose) {
16-
logInfo("Parsing OpenAPI spec...");
17-
}
18-
const openApiDoc = (await SwaggerParser.bundle(input)) as OpenAPIV3.Document;
19-
if (verbose) {
20-
logSuccess("Parsing finished.");
20+
logInfo("Resolving config...");
2121
}
22+
const fileConfig = await loadConfig(params.config);
23+
const config = deepMerge(DEFAULT_GENERATE_OPTIONS, fileConfig ?? {}, {
24+
...params,
25+
excludeTags: params.excludeTags?.split(","),
26+
});
2227

2328
if (verbose) {
24-
logInfo("Running check...");
29+
logInfo("Parsing OpenAPI spec...");
2530
}
26-
const errorMessages = checkOpenAPIDoc(openApiDoc, {
27-
input,
28-
excludeTags: excludeTags.split(","),
29-
...params,
30-
});
31+
const openApiDoc = (await SwaggerParser.bundle(config.input)) as OpenAPIV3.Document;
3132

3233
if (verbose) {
33-
logInfo(`TIME: ${Date.now() - start}ms`);
34+
logInfo("Running check...");
3435
}
36+
const errorMessages = checkOpenAPIDoc(openApiDoc, config);
3537

3638
if (errorMessages.length === 0) {
37-
logSuccess("Check finished.");
39+
logSuccess(`Time: ${Date.now() - start}ms`);
3840
} else {
39-
throw new Error(`Check finished. Found ${errorMessages.length} issues.`);
41+
throw new Error(`Found ${errorMessages.length} issues. Time: ${Date.now() - start}ms`);
4042
}
4143
}

0 commit comments

Comments
 (0)