Skip to content

Commit

Permalink
feat: enrich snippets files
Browse files Browse the repository at this point in the history
  • Loading branch information
shortcuts committed Nov 20, 2024
1 parent 8bff736 commit 376fa82
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
1 change: 1 addition & 0 deletions scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@actions/core": "1.11.1",
"@actions/exec": "1.1.1",
"@actions/io": "1.1.3",
"@apidevtools/json-schema-ref-parser": "^11.7.2",
"@har-sdk/oas": "2.10.0",
"@octokit/rest": "21.0.2",
"@types/express": "5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/specs/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export async function bundleSpecsForDoc(bundledPath: string, clientName: string)
const tagsDefinitions = bundledSpec.tags;
const codeSamples = await transformGeneratedSnippetsToCodeSamples(clientName);

await bundleCodeSamplesForDoc(JSON.parse(JSON.stringify(codeSamples)), clientName);
await bundleCodeSamplesForDoc(bundledSpec, JSON.parse(JSON.stringify(codeSamples)), clientName);

for (const [pathKey, pathMethods] of Object.entries(bundledSpec.paths)) {
for (const [method, specMethod] of Object.entries(pathMethods)) {
Expand Down
38 changes: 33 additions & 5 deletions scripts/specs/snippets.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import $RefParser from '@apidevtools/json-schema-ref-parser';
import fsp from 'fs/promises';

import { GENERATORS, capitalize, createClientName, exists, toAbsolutePath } from '../common.js';
import type { Language } from '../types.js';
import { GENERATORS, LANGUAGES, capitalize, createClientName, exists, toAbsolutePath } from '../common.js';
import type { Language, Spec } from '../types.js';

import type { CodeSamples, OpenAPICodeSample, SampleForOperation } from './types.js';
import type { CodeSamples, CodeSamplesWithAPIDefinition, OpenAPICodeSample, SampleForOperation } from './types.js';

export function getCodeSampleLabel(language: Language): OpenAPICodeSample['label'] {
switch (language) {
Expand All @@ -19,7 +20,8 @@ export function getCodeSampleLabel(language: Language): OpenAPICodeSample['label
}

// Iterates over the result of `transformSnippetsToCodeSamples` in order to generate a JSON file for the doc to consume.
export async function bundleCodeSamplesForDoc(codeSamples: CodeSamples, clientName: string): Promise<void> {
export async function bundleCodeSamplesForDoc(spec: Spec, codeSamples: CodeSamples, clientName: string): Promise<void> {
// first we build the end JSON file with our given code samples
for (const [language, operationWithSamples] of Object.entries(codeSamples)) {
for (const [operation, samples] of Object.entries(operationWithSamples)) {
if (operation === 'import') {
Expand Down Expand Up @@ -48,7 +50,33 @@ export async function bundleCodeSamplesForDoc(codeSamples: CodeSamples, clientNa
}
}

await fsp.writeFile(toAbsolutePath(`docs/bundled/${clientName}-snippets.json`), JSON.stringify(codeSamples, null, 2));
const codeSamplesWithParameters = { ...codeSamples } as CodeSamplesWithAPIDefinition;
const dereferencedSpec = (await $RefParser.dereference(spec, {
mutateInputSchema: false,
dereference: { circular: 'ignore' },
})) as Spec;

for (const [_, operations] of Object.entries(dereferencedSpec.paths)) {
for (const operation of Object.values(operations)) {
for (const lang of LANGUAGES) {
if (operation.operationId in codeSamplesWithParameters[lang]) {
codeSamplesWithParameters[lang][operation.operationId].parameters = operation.parameters || [];
codeSamplesWithParameters[lang][operation.operationId].responses = operation.responses || {};

if (operation.requestBody?.content?.['application/json']?.schema?.properties) {
codeSamplesWithParameters[lang][operation.operationId].parameters.push(
...new Set([operation.requestBody?.content?.['application/json']?.schema?.properties]),
);
}
}
}
}
}

await fsp.writeFile(
toAbsolutePath(`docs/bundled/${clientName}-snippets.json`),
JSON.stringify(codeSamplesWithParameters, null, 2),
);
}

// Reads the generated `docs/snippets/` file for every languages of the given `clientName` and builds an hashmap of snippets per operationId per language.
Expand Down
8 changes: 8 additions & 0 deletions scripts/specs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ export type BaseBuildSpecsOptions = {
useCache: boolean;
};

export type SampleForOperationWithAPIDefinition = SampleForOperation & {
parameters: Array<Record<string, any>>;
responses: Record<string, Record<string, any>>;
};
export type CodeSamplesWithAPIDefinition = Record<Language, Record<string, SampleForOperationWithAPIDefinition>>;

export type SampleForOperation = Record<string, string>;
export type CodeSamples = Record<Language, Record<string, SampleForOperation>>;

export type OpenAPICodeSample = {
lang:
| 'c'
| 'cURL'
| 'c++'
| 'coffeescript'
| 'csharp'
Expand All @@ -38,6 +45,7 @@ export type OpenAPICodeSample = {
| 'typescript';
label:
| 'C'
| 'curl'
| 'C#'
| 'C++'
| 'CoffeeScript'
Expand Down
26 changes: 17 additions & 9 deletions scripts/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type config from '../config/clients.config.json';

import type { CodeSamples } from './specs/types.js';
import type { OpenAPICodeSample } from './specs/types.js';

/**
* Config.
Expand Down Expand Up @@ -46,6 +46,8 @@ export type Spec = {
paths: Path;
components: {
schemas: Record<string, any>;
parameters: Record<string, any>;
responses: Record<string, any>;
securitySchemes: Partial<{ appId?: Record<string, any>; apiKey?: Record<string, any> }>;
};
};
Expand Down Expand Up @@ -77,11 +79,17 @@ type Method = 'delete' | 'get' | 'options' | 'patch' | 'post' | 'put';
/**
* Paths of a spec.
*/
type Path = Record<
Method,
Record<string, any> & {
operationId: string;
'x-codeSamples': CodeSamples[];
summary: string;
}
>;
export type Path = Record<string, Record<Method, Operation>>;

export type Operation = {
operationId: string;
'x-codeSamples': OpenAPICodeSample[];
summary: string;
requestBody?: {
required: boolean;
description: string;
content?: { 'application/json'?: { schema?: { properties?: Record<string, any> } } };
};
parameters: Array<Record<string, any>>;
responses: Record<string, Record<string, any>>;
} & Record<string, unknown>;

0 comments on commit 376fa82

Please sign in to comment.