Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ catalog:
typescript: 5.9.3
vitest: 4.0.8
'@types/node': 22.18.12
'@scalar/openapi-types': 0.5.2

# using named catalogs to align packages in /tests with /samples
catalogs:
Expand Down
3 changes: 2 additions & 1 deletion docs/src/pages/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ $ orval --config ./api/orval.config.js

### Project

The `--project` option, shorthand `-p`, can be used to focus on one project of your Orval config.
The `--project` option, shorthand `-p`, can be used to focus on projects of your Orval config.

```bash
$ orval --project petstore
$ orval --project dogstore catstore
```

### Watch
Expand Down
97 changes: 0 additions & 97 deletions docs/src/pages/reference/configuration/input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,6 @@ export default defineConfig({
});
```

Using a secure URL target with authentication:

```js
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
input: {
target: 'https://example.com/api-docs/v2/swagger.yaml',
parserOptions: {
resolve: {
http: {
headers: {
Authorization:
'Basic ' + Buffer.from('username:password').toString('base64'),
},
},
},
},
},
},
});
```

## validation

Type: `Boolean | Object`

Default value: `false`.

To enforce the quality of your OpenAPI specification, Orval supports validating specifications with the <a href="https://github.com/IBM/openapi-validator" target="_blank">OpenAPI linter from IBM</a>.

Specifying `true` will by default use the <a href="https://github.com/IBM/openapi-validator/blob/main/docs/ibm-cloud-rules.md"><em>IBM Cloud Validation Ruleset</em></a>.
Specifying an `Object` will use the provided ruleset instead. Learn more about creating rulesets <a href="https://docs.stoplight.io/docs/spectral/aa15cdee143a1-java-script-ruleset-format">here</a>.

```js
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
input: {
validation: true,
},
},
});
```

## override

Type: `Object`.
Expand Down Expand Up @@ -172,53 +125,3 @@ export default defineConfig({
},
});
```

## converterOptions

Type: `Object`.

Default Value: `{}`.

Orval converts Swagger 2.0 definitions into OpenAPI 3.0.x using [swagger2openapi](https://github.com/Mermade/oas-kit/tree/main/packages/swagger2openapi). Use the `converterOptions` property to provide custom config for that. See the available options [here](https://github.com/orval-labs/orval/blob/next/src/types/swagger2openapi.d.ts#L10).

Example:

```js
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
input: {
converterOptions: {
patch: true,
indent: 2,
},
},
},
});
```

## parserOptions

Type: `Object`.

Default Value: `{ resolve: { github: githubResolver, http: { safeUrlResolver: false } }, validate: true }`.

Orval utilizes a parser to process multiple file specifications. This behavior can be customized using the `parserOptions` property. See the [available options](https://apidevtools.com/swagger-parser/options.html) for configuration.
By default, Orval includes a GitHub parser, but you can add your own for private specifications or other specific needs.

The specification is automatically validated by default.

```js
import { defineConfig } from 'orval';

export default defineConfig({
petstore: {
input: {
parserOptions: {
resolve: { gitlab: gitlabResolver },
},
},
},
});
```
8 changes: 1 addition & 7 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,14 @@
"@types/debug": "^4.1.12",
"@types/esutils": "^2.0.2",
"@types/fs-extra": "^11.0.4",
"@types/swagger2openapi": "^7.0.4",
"eslint": "catalog:",
"openapi-types": "^12.1.3",
"rimraf": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
},
"dependencies": {
"@apidevtools/swagger-parser": "^12.1.0",
"@ibm-cloud/openapi-ruleset": "^1.33.1",
"@stoplight/spectral-core": "^1.20.0",
"@scalar/openapi-types": "catalog:",
"acorn": "^8.15.0",
"chalk": "^5.6.2",
"compare-versions": "^6.1.1",
Expand All @@ -47,9 +43,7 @@
"esutils": "2.0.3",
"fs-extra": "^11.3.2",
"globby": "16.0.0",
"openapi3-ts": "4.5.0",
"remeda": "^2.32.0",
"swagger2openapi": "^7.0.8",
"typedoc": "^0.28.14"
},
"stableVersion": "8.0.0-rc.1"
Expand Down
102 changes: 46 additions & 56 deletions packages/core/src/generators/component-definition.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,58 @@
import type {
ComponentsObject,
ReferenceObject,
RequestBodyObject,
ResponseObject,
} from 'openapi3-ts/oas30';
import { isEmptyish } from 'remeda';
import { entries, isEmptyish } from 'remeda';

import { getResReqTypes } from '../getters';
import type { ContextSpecs, GeneratorSchema } from '../types';
import type {
ContextSpec,
GeneratorSchema,
OpenApiComponentsObject,
} from '../types';
import { jsDoc, pascal, sanitize } from '../utils';

export const generateComponentDefinition = (
export function generateComponentDefinition(
responses:
| ComponentsObject['responses']
| ComponentsObject['requestBodies'] = {},
context: ContextSpecs,
| OpenApiComponentsObject['responses']
| OpenApiComponentsObject['requestBodies'] = {},
context: ContextSpec,
suffix: string,
): GeneratorSchema[] => {
): GeneratorSchema[] {
if (isEmptyish(responses)) {
return [];
}

return Object.entries(responses).reduce<GeneratorSchema[]>(
(
acc,
[name, response]: [
string,
ReferenceObject | RequestBodyObject | ResponseObject,
],
) => {
const allResponseTypes = getResReqTypes(
[[suffix, response]],
name,
context,
'void',
);

const imports = allResponseTypes.flatMap(({ imports }) => imports);
const schemas = allResponseTypes.flatMap(({ schemas }) => schemas);

const type = allResponseTypes.map(({ value }) => value).join(' | ');

const modelName = sanitize(`${pascal(name)}${suffix}`, {
underscore: '_',
whitespace: '_',
dash: true,
es5keyword: true,
es5IdentifierName: true,
const generatorSchemas: GeneratorSchema[] = [];
for (const [name, response] of entries(responses)) {
const allResponseTypes = getResReqTypes(
[[suffix, response]],
name,
context,
'void',
);

const imports = allResponseTypes.flatMap(({ imports }) => imports);
const schemas = allResponseTypes.flatMap(({ schemas }) => schemas);

const type = allResponseTypes.map(({ value }) => value).join(' | ');

const modelName = sanitize(`${pascal(name)}${suffix}`, {
underscore: '_',
whitespace: '_',
dash: true,
es5keyword: true,
es5IdentifierName: true,
});
const doc = jsDoc(response);
const model = `${doc}export type ${modelName} = ${type || 'unknown'};\n`;

generatorSchemas.push(...schemas);

if (modelName !== type) {
generatorSchemas.push({
name: modelName,
model,
imports,
});
const doc = jsDoc(response as ResponseObject | RequestBodyObject);
const model = `${doc}export type ${modelName} = ${type || 'unknown'};\n`;

acc.push(...schemas);

if (modelName !== type) {
acc.push({
name: modelName,
model,
imports,
});
}
}
}

return acc;
},
[],
);
};
return generatorSchemas;
}
Loading