Skip to content

Commit c36838d

Browse files
authored
Ensure not required parameters are created as optional properties (#1053)
* Add missing 'vite' dependency * Ensure not required params are created as optional properties (#1052) According to the OpenAPI 3.1.0 spec, a parameter is required if one of these matches: - it has 'in: "path"' - it has 'required: true' See spec at Parameter Object - Fixed Fields: https://spec.openapis.org/oas/v3.1.0#fixed-fields-9 Fixes #1052
1 parent 6408fa6 commit c36838d

7 files changed

+189
-150
lines changed

examples/github-api-next.ts

+61-61
Large diffs are not rendered by default.

examples/github-api.ts

+61-61
Large diffs are not rendered by default.

examples/octokit-ghes-3.6-diff-to-api.ts

+28-28
Original file line numberDiff line numberDiff line change
@@ -5665,13 +5665,13 @@ export interface components {
56655665
};
56665666
parameters: {
56675667
/** @description The number of results per page (max 100). */
5668-
"per-page": number;
5668+
"per-page"?: number;
56695669
/** @description Page number of the results to fetch. */
5670-
page: number;
5670+
page?: number;
56715671
/** @description The unique identifier of the hook. */
56725672
"hook-id": number;
56735673
/** @description The direction to sort the results by. */
5674-
direction: "asc" | "desc";
5674+
direction?: "asc" | "desc";
56755675
/** @description The unique identifier of the key. */
56765676
"key-ids": string;
56775677
/** @description The unique identifier of the team. */
@@ -5687,7 +5687,7 @@ export interface components {
56875687
/** @description The unique identifier of the token. */
56885688
"token-id": number;
56895689
/** @description Only show notifications updated after the given time. This is a timestamp in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format: `YYYY-MM-DDTHH:MM:SSZ`. */
5690-
since: string;
5690+
since?: string;
56915691
/** @description The unique identifier of the installation. */
56925692
"installation-id": number;
56935693
/** @description The unique identifier of the grant. */
@@ -5701,7 +5701,7 @@ export interface components {
57015701
/** @description The slug version of the enterprise name. You can also substitute this value with the enterprise id. */
57025702
enterprise: string;
57035703
/** @description A search phrase. For more information, see [Searching the audit log](https://docs.github.com/[email protected]/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#searching-the-audit-log). */
5704-
"audit-log-phrase": string;
5704+
"audit-log-phrase"?: string;
57055705
/**
57065706
* @description The event types to include:
57075707
*
@@ -5711,33 +5711,33 @@ export interface components {
57115711
*
57125712
* The default is `web`.
57135713
*/
5714-
"audit-log-include": "web" | "git" | "all";
5714+
"audit-log-include"?: "web" | "git" | "all";
57155715
/** @description A cursor, as given in the [Link header](https://docs.github.com/[email protected]/rest/overview/resources-in-the-rest-api#link-header). If specified, the query only searches for events after this cursor. */
5716-
"audit-log-after": string;
5716+
"audit-log-after"?: string;
57175717
/** @description A cursor, as given in the [Link header](https://docs.github.com/[email protected]/rest/overview/resources-in-the-rest-api#link-header). If specified, the query only searches for events before this cursor. */
5718-
"audit-log-before": string;
5718+
"audit-log-before"?: string;
57195719
/**
57205720
* @description The order of audit log events. To list newest events first, specify `desc`. To list oldest events first, specify `asc`.
57215721
*
57225722
* The default is `desc`.
57235723
*/
5724-
"audit-log-order": "desc" | "asc";
5724+
"audit-log-order"?: "desc" | "asc";
57255725
/** @description Set to `open` or `resolved` to only list secret scanning alerts in a specific state. */
5726-
"secret-scanning-alert-state": "open" | "resolved";
5726+
"secret-scanning-alert-state"?: "open" | "resolved";
57275727
/**
57285728
* @description A comma-separated list of secret types to return. By default all secret types are returned.
57295729
* See "[Secret scanning patterns](https://docs.github.com/[email protected]/code-security/secret-scanning/secret-scanning-patterns#supported-secrets-for-advanced-security)"
57305730
* for a complete list of secret types.
57315731
*/
5732-
"secret-scanning-alert-secret-type": string;
5732+
"secret-scanning-alert-secret-type"?: string;
57335733
/** @description A comma-separated list of resolutions. Only secret scanning alerts with one of these resolutions are listed. Valid resolutions are `false_positive`, `wont_fix`, `revoked`, `pattern_edited`, `pattern_deleted` or `used_in_tests`. */
5734-
"secret-scanning-alert-resolution": string;
5734+
"secret-scanning-alert-resolution"?: string;
57355735
/** @description The property to sort the results by. `created` means when the alert was created. `updated` means when the alert was updated or resolved. */
5736-
"secret-scanning-alert-sort": "created" | "updated";
5736+
"secret-scanning-alert-sort"?: "created" | "updated";
57375737
/** @description A cursor, as given in the [Link header](https://docs.github.com/[email protected]/rest/overview/resources-in-the-rest-api#link-header). If specified, the query only searches for events before this cursor. */
5738-
"pagination-before": string;
5738+
"pagination-before"?: string;
57395739
/** @description A cursor, as given in the [Link header](https://docs.github.com/[email protected]/rest/overview/resources-in-the-rest-api#link-header). If specified, the query only searches for events after this cursor. */
5740-
"pagination-after": string;
5740+
"pagination-after"?: string;
57415741
/** @description The unique identifier of the group. */
57425742
"group-id": number;
57435743
/** @description The slug of the team name. */
@@ -5747,19 +5747,19 @@ export interface components {
57475747
/** @description The name of the repository. The name is not case sensitive. */
57485748
repo: string;
57495749
/** @description Returns someone's workflow runs. Use the login for the user who created the `push` associated with the check suite or workflow run. */
5750-
actor: string;
5750+
actor?: string;
57515751
/** @description Returns workflow runs associated with a branch. Use the name of the branch of the `push`. */
5752-
"workflow-run-branch": string;
5752+
"workflow-run-branch"?: string;
57535753
/** @description Returns workflow run triggered by the event you specify. For example, `push`, `pull_request` or `issue`. For more information, see "[Events that trigger workflows](https://docs.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows)." */
5754-
event: string;
5754+
event?: string;
57555755
/** @description Returns workflow runs with the check run `status` or `conclusion` that you specify. For example, a conclusion can be `success` or a status can be `in_progress`. Only GitHub can set a status of `waiting` or `requested`. */
5756-
"workflow-run-status": "completed" | "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out" | "in_progress" | "queued" | "requested" | "waiting";
5756+
"workflow-run-status"?: "completed" | "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out" | "in_progress" | "queued" | "requested" | "waiting";
57575757
/** @description Returns workflow runs created within the given date-time range. For more information on the syntax, see "[Understanding the search syntax](https://docs.github.com/[email protected]/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax#query-for-dates)." */
5758-
created: string;
5758+
created?: string;
57595759
/** @description If `true` pull requests are omitted from the response (empty array). */
5760-
"exclude-pull-requests": boolean;
5760+
"exclude-pull-requests"?: boolean;
57615761
/** @description Returns workflow runs with the `check_suite_id` that you specify. */
5762-
"workflow-run-check-suite-id": number;
5762+
"workflow-run-check-suite-id"?: number;
57635763
/** @description The unique identifier of the workflow run. */
57645764
"run-id": number;
57655765
/** @description The attempt number of the workflow run. */
@@ -5769,23 +5769,23 @@ export interface components {
57695769
/** @description The unique identifier of the autolink. */
57705770
"autolink-id": number;
57715771
/** @description The name of a code scanning tool. Only results by this tool will be listed. You can specify the tool by using either `tool_name` or `tool_guid`, but not both. */
5772-
"tool-name": components["schemas"]["code-scanning-analysis-tool-name"];
5772+
"tool-name"?: components["schemas"]["code-scanning-analysis-tool-name"];
57735773
/** @description The GUID of a code scanning tool. Only results by this tool will be listed. Note that some code scanning tools may not include a GUID in their analysis data. You can specify the tool by using either `tool_guid` or `tool_name`, but not both. */
5774-
"tool-guid": components["schemas"]["code-scanning-analysis-tool-guid"];
5774+
"tool-guid"?: components["schemas"]["code-scanning-analysis-tool-guid"];
57755775
/** @description The full path, relative to the repository root, of the dependency manifest file. */
5776-
"manifest-path": string;
5776+
"manifest-path"?: string;
57775777
/** @description The unique identifier of the key. */
57785778
"key-id": number;
57795779
/** @description The unique identifier of the release. */
57805780
"release-id": number;
57815781
/** @description The number that identifies an alert. You can find this at the end of the URL for a code scanning alert within GitHub, and in the `number` field in the response from the `GET /repos/{owner}/{repo}/code-scanning/alerts` operation. */
57825782
"alert-number": components["schemas"]["alert-number"];
57835783
/** @description A repository ID. Only return repositories with an ID greater than this ID. */
5784-
"since-repo": number;
5784+
"since-repo"?: number;
57855785
/** @description Used for pagination: the index of the first result to return. */
5786-
"start-index": number;
5786+
"start-index"?: number;
57875787
/** @description Used for pagination: the number of results to return. */
5788-
count: number;
5788+
count?: number;
57895789
/** @description Identifier generated by the GitHub SCIM endpoint. */
57905790
"scim-group-id": string;
57915791
/** @description The unique identifier of the SCIM user. */

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"execa": "^6.1.0",
7070
"prettier": "^2.8.7",
7171
"typescript": "^5.0.3",
72+
"vite": "^4.1.4",
7273
"vite-node": "^0.29.8",
7374
"vitest": "^0.29.8"
7475
}

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/transform/components-object.ts

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ export default function transformComponentsObject(components: ComponentsObject,
8080
)
8181
);
8282
} else {
83+
if (parameterObject.in !== "path" && !parameterObject.required) {
84+
key = tsOptionalProperty(key);
85+
}
8386
const parameterType = transformParameterObject(parameterObject, {
8487
path: `#/components/parameters/${name}`,
8588
ctx: { ...ctx, indentLv },

test/components-object.test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const basicSchema: ComponentsObject = {
4141
Search: {
4242
name: "search",
4343
in: "query",
44+
required: true,
4445
schema: { type: "string" },
4546
},
4647
},
@@ -78,6 +79,22 @@ const basicSchema: ComponentsObject = {
7879
},
7980
};
8081

82+
const optionalParamSchema: ComponentsObject = {
83+
parameters: {
84+
myParam: {
85+
name: "myParam",
86+
in: "query",
87+
required: false,
88+
schema: { type: "string" },
89+
},
90+
myParam2: {
91+
name: "myParam2",
92+
in: "query",
93+
schema: { type: "string" },
94+
},
95+
},
96+
};
97+
8198
describe("Components Object", () => {
8299
test("basic", () => {
83100
const generated = transformComponentsObject(basicSchema, options);
@@ -219,4 +236,19 @@ describe("Components Object", () => {
219236
});
220237
});
221238
});
239+
240+
test("parameters with required: false", () => {
241+
const generated = transformComponentsObject(optionalParamSchema, options);
242+
expect(generated).toBe(`{
243+
schemas: never;
244+
responses: never;
245+
parameters: {
246+
myParam?: string;
247+
myParam2?: string;
248+
};
249+
requestBodies: never;
250+
headers: never;
251+
pathItems: never;
252+
}`);
253+
});
222254
});

0 commit comments

Comments
 (0)