Skip to content

Commit 1fdaa2d

Browse files
authored
Skip resolving in components.examples (#977)
1 parent 502acb1 commit 1fdaa2d

9 files changed

+9338
-13
lines changed

examples/github-api-next.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -12306,7 +12306,7 @@ export interface components {
1230612306
require_code_owner_reviews: boolean;
1230712307
required_approving_review_count?: number;
1230812308
/**
12309-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request.
12309+
* @description Whether the most recent push must be approved by someone other than the person who pushed it.
1231012310
* @default false
1231112311
*/
1231212312
require_last_push_approval?: boolean;
@@ -12592,7 +12592,7 @@ export interface components {
1259212592
require_code_owner_reviews?: boolean;
1259312593
required_approving_review_count?: number;
1259412594
/**
12595-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request.
12595+
* @description Whether the most recent push must be approved by someone other than the person who pushed it.
1259612596
* @default false
1259712597
*/
1259812598
require_last_push_approval?: boolean;
@@ -90770,7 +90770,7 @@ export interface operations {
9077090770
/** @description Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. */
9077190771
required_approving_review_count?: number;
9077290772
/**
90773-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request. Default: `false`.
90773+
* @description Whether the most recent push must be approved by someone other than the person who pushed it. Default: `false`.
9077490774
* @default false
9077590775
*/
9077690776
require_last_push_approval?: boolean;
@@ -90935,7 +90935,7 @@ export interface operations {
9093590935
/** @description Specifies the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. */
9093690936
required_approving_review_count?: number;
9093790937
/**
90938-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request. Default: `false`
90938+
* @description Whether the most recent push must be approved by someone other than the person who pushed it. Default: `false`
9093990939
* @default false
9094090940
*/
9094190941
require_last_push_approval?: boolean;

examples/github-api.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -15230,7 +15230,7 @@ export interface components {
1523015230
/** @example 2 */
1523115231
required_approving_review_count?: number;
1523215232
/**
15233-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request.
15233+
* @description Whether the most recent push must be approved by someone other than the person who pushed it.
1523415234
* @default false
1523515235
* @example true
1523615236
*/
@@ -15598,7 +15598,7 @@ export interface components {
1559815598
require_code_owner_reviews?: boolean;
1559915599
required_approving_review_count?: number;
1560015600
/**
15601-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request.
15601+
* @description Whether the most recent push must be approved by someone other than the person who pushed it.
1560215602
* @default false
1560315603
*/
1560415604
require_last_push_approval?: boolean;
@@ -95282,7 +95282,7 @@ export interface operations {
9528295282
/** @description Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. */
9528395283
required_approving_review_count?: number;
9528495284
/**
95285-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request. Default: `false`.
95285+
* @description Whether the most recent push must be approved by someone other than the person who pushed it. Default: `false`.
9528695286
* @default false
9528795287
*/
9528895288
require_last_push_approval?: boolean;
@@ -95447,7 +95447,7 @@ export interface operations {
9544795447
/** @description Specifies the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers. */
9544895448
required_approving_review_count?: number;
9544995449
/**
95450-
* @description Whether someone other than the person who last pushed to the branch must approve this pull request. Default: `false`
95450+
* @description Whether the most recent push must be approved by someone other than the person who pushed it. Default: `false`
9545195451
* @default false
9545295452
*/
9545395453
require_last_push_approval?: boolean;

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

+9,248
Large diffs are not rendered by default.

scripts/download-schemas.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export const singleFile = {
99
"https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.yaml",
1010
"github-api-next":
1111
"https://raw.githubusercontent.com/github/rest-api-description/main/descriptions-next/api.github.com/api.github.com.yaml",
12+
"octokit-ghes-3.6-diff-to-api":
13+
"https://raw.githubusercontent.com/octokit/octokit-next.js/main/cache/types-openapi/ghes-3.6-diff-to-api.github.com.json",
1214
"stripe-api": "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.yaml",
1315
};
1416
export const multiFile = {

src/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ async function openapiTS(
5959
// 1. load schema (and subschemas)
6060
const allSchemas: { [id: string]: Subschema } = {};
6161
const schemaURL: URL = typeof schema === "string" ? resolveSchema(schema) : (schema as URL);
62-
6362
await load(schemaURL, {
6463
...ctx,
6564
auth: options.auth,

src/load.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -195,20 +195,28 @@ export default async function load(
195195
}
196196

197197
// 2. resolve $refs
198+
const currentSchema = options.schemas[schemaID].schema;
199+
200+
// 2a. remove "components.examples" first
201+
if (options.schemas[schemaID].hint === "OpenAPI3") {
202+
if ("components" in currentSchema && currentSchema.components && "examples" in currentSchema.components)
203+
delete currentSchema.components.examples;
204+
}
205+
198206
const refPromises: Promise<any>[] = [];
199-
walk(options.schemas[schemaID].schema, (rawNode, nodePath) => {
207+
walk(currentSchema, (rawNode, nodePath) => {
200208
// filter custom properties from allOf, anyOf, oneOf
201209
for (const k of ["allOf", "anyOf", "oneOf"]) {
202210
if (Array.isArray(rawNode[k])) {
203211
rawNode[k] = (rawNode as any)[k].filter((o: SchemaObject | ReferenceObject) => {
204-
if (!("$ref" in o)) return true;
212+
if (!("$ref" in o) || typeof o.$ref !== "string") return true;
205213
const ref = parseRef(o.$ref);
206214
return !ref.path.some((i) => i.startsWith("x-")); // ignore all custom "x-*" properties
207215
});
208216
}
209217
}
210218

211-
if (!("$ref" in rawNode)) return;
219+
if (!("$ref" in rawNode) || typeof rawNode.$ref !== "string") return;
212220
const node = rawNode as unknown as ReferenceObject;
213221

214222
const ref = parseRef(node.$ref);
@@ -253,7 +261,7 @@ export default async function load(
253261
if (schemaID === ".") {
254262
for (const subschemaID of Object.keys(options.schemas)) {
255263
walk(options.schemas[subschemaID].schema, (rawNode) => {
256-
if (!("$ref" in rawNode)) return;
264+
if (!("$ref" in rawNode) || typeof rawNode.$ref !== "string") return;
257265
const node = rawNode as unknown as ReferenceObject;
258266

259267
const ref = parseRef(node.$ref);

test/cli.test.ts

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ describe("CLI", () => {
1818
const { stdout } = await execa(cmd, ["./test/fixtures/github-api-next.yaml"], { cwd });
1919
expect(stdout).toBe(expected);
2020
}, 30000);
21+
test("Octokit GHES 3.6 Diff to API", async () => {
22+
const expected = fs.readFileSync(new URL("./examples/octokit-ghes-3.6-diff-to-api.ts", cwd), "utf8").trim();
23+
const { stdout } = await execa(cmd, ["./test/fixtures/octokit-ghes-3.6-diff-to-api.yaml"], { cwd });
24+
expect(stdout).toBe(expected);
25+
}, 30000);
2126
test("Stripe API", async () => {
2227
const expected = fs.readFileSync(new URL("./examples/stripe-api.ts", cwd), "utf8").trim();
2328
const { stdout } = await execa(cmd, ["./test/fixtures/stripe-api.yaml"], { cwd });

test/components-object.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ const basicSchema: ComponentsObject = {
5555
},
5656
},
5757
},
58+
// "examples" should just be ignored
59+
examples: {
60+
ExampleObject: {
61+
value: {
62+
name: "Example",
63+
$ref: "foo.yml#/components/schemas/Bar",
64+
},
65+
},
66+
},
5867
headers: {
5968
Auth: { schema: { type: "string" } },
6069
},

test/index.test.ts

+54
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,54 @@ export interface components {
6161
6262
export type external = Record<string, never>;
6363
64+
export type operations = Record<string, never>;
65+
`);
66+
});
67+
68+
test("components.examples are skipped", async () => {
69+
const generated = await openapiTS({
70+
openapi: "3.0",
71+
info: { title: "Test", version: "1.0" },
72+
components: {
73+
schemas: {
74+
Example: {
75+
type: "object",
76+
properties: {
77+
name: { type: "string" },
78+
$ref: { type: "string" },
79+
},
80+
required: ["name", "$ref"],
81+
},
82+
},
83+
examples: {
84+
Example: {
85+
value: {
86+
name: "Test",
87+
$ref: "fake.yml#/components/schemas/Example",
88+
},
89+
},
90+
},
91+
},
92+
});
93+
expect(generated).toBe(`${BOILERPLATE}
94+
export type paths = Record<string, never>;
95+
96+
export interface components {
97+
schemas: {
98+
Example: {
99+
name: string;
100+
$ref: string;
101+
};
102+
};
103+
responses: never;
104+
parameters: never;
105+
requestBodies: never;
106+
headers: never;
107+
pathItems: never;
108+
}
109+
110+
export type external = Record<string, never>;
111+
64112
export type operations = Record<string, never>;
65113
`);
66114
});
@@ -417,6 +465,12 @@ export type operations = Record<string, never>;
417465
expect(generated).toBe(fs.readFileSync(new URL("./github-api-next.ts", EXAMPLES_DIR), "utf8"));
418466
}, 30000);
419467
});
468+
describe("Octokit GHES 3.6 Diff to API", () => {
469+
test("default options", async () => {
470+
const generated = await openapiTS(new URL("./octokit-ghes-3.6-diff-to-api.yaml", FIXTURES_DIR));
471+
expect(generated).toBe(fs.readFileSync(new URL("./octokit-ghes-3.6-diff-to-api.ts", EXAMPLES_DIR), "utf8"));
472+
}, 30000);
473+
});
420474
describe("Stripe", () => {
421475
test("default options", async () => {
422476
const generated = await openapiTS(new URL("./stripe-api.yaml", FIXTURES_DIR));

0 commit comments

Comments
 (0)