Skip to content

Commit

Permalink
Merge pull request #731 from bitgopatmcl/base-url-support
Browse files Browse the repository at this point in the history
Add support for specifying base URL
  • Loading branch information
bitgopatmcl authored Apr 2, 2024
2 parents 03b6239 + 99b98dc commit 8d18a84
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 3 deletions.
13 changes: 13 additions & 0 deletions packages/openapi-generator/src/apiSpec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as swc from '@swc/core';
import * as E from 'fp-ts/Either';
import type { Block } from 'comment-parser';

import { parsePlainInitializer } from './codec';
import type { Project } from './project';
import { resolveLiteralOrIdentifier } from './resolveInit';
import { parseRoute, type Route } from './route';
import { SourceFile } from './sourceFile';
import { OpenAPIV3 } from 'openapi-types';

export function parseApiSpec(
project: Project,
Expand Down Expand Up @@ -83,3 +85,14 @@ export function parseApiSpec(

return E.right(result);
}

export function parseApiSpecComment(
comment: Block | undefined,
): OpenAPIV3.ServerObject | undefined {
if (comment === undefined) {
return undefined;
}
const description = comment.description;
const url = comment.tags.find((tag) => tag.tag === 'url')?.name;
return url !== undefined ? { url, description } : undefined;
}
9 changes: 8 additions & 1 deletion packages/openapi-generator/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import * as E from 'fp-ts/Either';
import * as fs from 'fs';
import * as p from 'path';
import type { Expression } from '@swc/core';
import type { OpenAPIV3 } from 'openapi-types';

import { parseApiSpec } from './apiSpec';
import { parseApiSpec, parseApiSpecComment } from './apiSpec';
import { getRefs } from './ref';
import { convertRoutesToOpenAPI } from './openapi';
import type { Route } from './route';
Expand Down Expand Up @@ -106,6 +107,7 @@ const app = command({
}

let apiSpec: Route[] = [];
let servers: OpenAPIV3.ServerObject[] = [];
for (const symbol of Object.values(entryPoint.symbols.declarations)) {
if (symbol.init === undefined) {
continue;
Expand Down Expand Up @@ -136,6 +138,10 @@ const app = command({
process.exit(1);
}

const server = parseApiSpecComment(symbol.comment);
if (server !== undefined) {
servers.push(server);
}
apiSpec.push(...result.right);
}
if (apiSpec.length === 0) {
Expand Down Expand Up @@ -189,6 +195,7 @@ const app = command({
version,
description,
},
servers,
apiSpec,
components,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-generator/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { parseApiSpec } from './apiSpec';
export { parseApiSpec, parseApiSpecComment } from './apiSpec';
export { parseCodecInitializer, parsePlainInitializer } from './codec';
export { parseCommentBlock, type JSDoc } from './jsdoc';
export { convertRoutesToOpenAPI } from './openapi';
Expand Down
2 changes: 2 additions & 0 deletions packages/openapi-generator/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ function routeToOpenAPI(route: Route): [string, string, OpenAPIV3.OperationObjec

export function convertRoutesToOpenAPI(
info: OpenAPIV3.InfoObject,
servers: OpenAPIV3.ServerObject[],
routes: Route[],
schemas: Record<string, Schema>,
): OpenAPIV3.Document {
Expand Down Expand Up @@ -215,6 +216,7 @@ export function convertRoutesToOpenAPI(
return {
openapi: '3.0.3',
info,
...(servers.length > 0 ? { servers } : {}),
paths,
components: {
schemas: openapiSchemas,
Expand Down
48 changes: 47 additions & 1 deletion packages/openapi-generator/test/apiSpec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import test from 'node:test';
import type { NestedDirectoryJSON } from 'memfs';

import { TestProject } from './testProject';
import { parseApiSpec, type Route } from '../src';
import { parseApiSpec, parseApiSpecComment, type Route } from '../src';

async function testCase(
description: string,
Expand Down Expand Up @@ -219,3 +219,49 @@ testCase('computed property api spec', COMPUTED_PROPERTY, '/index.ts', {
},
],
});

const BASE_URL = {
'/index.ts': `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
/** An API spec
*
* @url /api/v1
**/
export const test = h.apiSpec({
'api.test': {
get: h.httpRoute({
path: '/test',
method: 'GET',
request: h.httpRequest({}),
response: {
200: t.string,
},
})
}
});`,
};

test('api spec comment parser', async () => {
const project = new TestProject(BASE_URL);

await project.parseEntryPoint('/index.ts');
const sourceFile = project.get('/index.ts');
if (sourceFile === undefined) {
throw new Error('could not find source file /index.ts');
}

let commentParsed = false;
sourceFile.symbols.declarations.forEach((symbol) => {
if (symbol.name === 'test') {
assert.deepEqual(parseApiSpecComment(symbol.comment), {
description: 'An API spec',
url: '/api/v1',
});
commentParsed = true;
}
});

assert(commentParsed);
});
1 change: 1 addition & 0 deletions packages/openapi-generator/test/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ async function testCase(

const actual = convertRoutesToOpenAPI(
{ title: 'Test', version: '1.0.0' },
[],
routes,
schemas,
);
Expand Down

0 comments on commit 8d18a84

Please sign in to comment.