diff --git a/.prettierignore b/.prettierignore index d27bbf0b..dd536776 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ coverage/ dist/ flake.lock +packages/openapi-generator/test/ diff --git a/package-lock.json b/package-lock.json index 908c4e95..8f91fab6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "Apache-2.0", "workspaces": [ - "packages/**" + "packages/*" ], "devDependencies": { "@semantic-release-extras/github-comment-specific": "1.0.7", @@ -13750,7 +13750,7 @@ "@types/resolve": "1.20.6", "c8": "9.1.0", "memfs": "4.9.2", - "typescript": "4.7.4" + "typescript": "^4.7.4" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.5.7", diff --git a/package.json b/package.json index 58f25e68..2bfc34ab 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "homepage": "https://github.com/BitGo/api-ts#readme", "workspaces": [ - "packages/**" + "packages/*" ], "packageManager": "npm@8.5.0", "scripts": { diff --git a/packages/openapi-generator/package.json b/packages/openapi-generator/package.json index b4513fdb..2889cdb1 100644 --- a/packages/openapi-generator/package.json +++ b/packages/openapi-generator/package.json @@ -17,7 +17,8 @@ "clean": "rm -rf -- dist", "format": "prettier --check .", "format:fix": "prettier --write .", - "test": "c8 --all --src src node --require @swc-node/register --test test/*.test.ts" + "test": "c8 --all --src src node --require @swc-node/register --test test/*.test.ts", + "test:target": "c8 --all --src src node --require @swc-node/register" }, "dependencies": { "@swc/core": "1.5.7", diff --git a/packages/openapi-generator/src/cli.ts b/packages/openapi-generator/src/cli.ts index fbd1039f..2bf98fe7 100644 --- a/packages/openapi-generator/src/cli.ts +++ b/packages/openapi-generator/src/cli.ts @@ -159,7 +159,7 @@ const app = command({ }); let schema: Schema | undefined; while (((schema = queue.pop()), schema !== undefined)) { - const refs = getRefs(schema); + const refs = getRefs(schema, project.right.getTypes()); for (const ref of refs) { if (components[ref.name] !== undefined) { continue; @@ -169,6 +169,7 @@ const app = command({ console.error(`Could not find '${ref.name}' from '${ref.location}'`); process.exit(1); } + const initE = findSymbolInitializer(project.right, sourceFile, ref.name); if (E.isLeft(initE)) { console.error( @@ -177,6 +178,7 @@ const app = command({ process.exit(1); } const [newSourceFile, init] = initE.right; + const codecE = parseCodecInitializer(project.right, newSourceFile, init); if (E.isLeft(codecE)) { console.error( diff --git a/packages/openapi-generator/src/codec.ts b/packages/openapi-generator/src/codec.ts index 3e52fd33..592eee0a 100644 --- a/packages/openapi-generator/src/codec.ts +++ b/packages/openapi-generator/src/codec.ts @@ -96,12 +96,6 @@ function codecIdentifier( } const name = id.property.value; - if (!objectImportSym.from.startsWith('.')) { - return E.left( - `Unimplemented named member reference '${objectImportSym.localName}.${name}' from '${objectImportSym.from}'`, - ); - } - const newInitE = findSymbolInitializer(project, source, [ objectImportSym.localName, name, @@ -360,9 +354,17 @@ export function parseCodecInitializer( if (schema.type !== 'ref') { return E.right(schema); } else { - const refSource = project.get(schema.location); + let refSource = project.get(schema.location); + if (refSource === undefined) { - return E.left(`Cannot find '${schema.name}' from '${schema.location}'`); + // schema.location might be a package name -> need to resolve the path from the project types + const path = project.getTypes()[schema.name]; + if (path === undefined) + return E.left(`Cannot find module '${schema.location}' in the project`); + refSource = project.get(path); + if (refSource === undefined) { + return E.left(`Cannot find '${schema.name}' from '${schema.location}'`); + } } const initE = findSymbolInitializer(project, refSource, schema.name); if (E.isLeft(initE)) { diff --git a/packages/openapi-generator/src/project.ts b/packages/openapi-generator/src/project.ts index 227b8eb5..9aa98cda 100644 --- a/packages/openapi-generator/src/project.ts +++ b/packages/openapi-generator/src/project.ts @@ -13,10 +13,12 @@ export class Project { private readonly knownImports: Record>; private files: Record; + private types: Record; constructor(files: Record = {}, knownImports = KNOWN_IMPORTS) { this.files = files; this.knownImports = knownImports; + this.types = {}; } add(path: string, sourceFile: SourceFile): void { @@ -42,19 +44,33 @@ export class Project { const src = await this.readFile(path); const sourceFile = await parseSource(path, src); + if (sourceFile === undefined) continue; + + // map types to their file path + for (const exp of sourceFile.symbols.exports) { + this.types[exp.exportedName] = path; + } + this.add(path, sourceFile); for (const sym of Object.values(sourceFile.symbols.imports)) { if (!sym.from.startsWith('.')) { - continue; - } - - const filePath = p.dirname(path); - const absImportPathE = this.resolve(filePath, sym.from); - if (E.isLeft(absImportPathE)) { - return absImportPathE; - } else if (!this.has(absImportPathE.right)) { - queue.push(absImportPathE.right); + // If we are not resolving a relative path, we need to resolve the entry point + const baseDir = p.dirname(sourceFile.path); + let entryPoint = this.resolveEntryPoint(baseDir, sym.from); + if (E.isLeft(entryPoint)) { + continue; + } else if (!this.has(entryPoint.right)) { + queue.push(entryPoint.right); + } + } else { + const filePath = p.dirname(path); + const absImportPathE = this.resolve(filePath, sym.from); + if (E.isLeft(absImportPathE)) { + return absImportPathE; + } else if (!this.has(absImportPathE.right)) { + queue.push(absImportPathE.right); + } } } for (const starExport of sourceFile.symbols.exportStarFiles) { @@ -75,6 +91,38 @@ export class Project { return await readFile(filename, 'utf8'); } + resolveEntryPoint(basedir: string, library: string): E.Either { + try { + const packageJson = resolve.sync(`${library}/package.json`, { + basedir, + extensions: ['.json'], + }); + const packageInfo = JSON.parse(fs.readFileSync(packageJson, 'utf8')); + + let typesEntryPoint = ''; + + if (packageInfo['types']) { + typesEntryPoint = packageInfo['types']; + } + + if (packageInfo['typings']) { + typesEntryPoint = packageInfo['typings']; + } + + if (!typesEntryPoint) { + return E.left(`Could not find types entry point for ${library}`); + } + + const entryPoint = resolve.sync(`${library}/${typesEntryPoint}`, { + basedir, + extensions: ['.ts', '.js'], + }); + return E.right(entryPoint); + } catch (err) { + return E.left(`Could not resolve entry point for ${library}: ${err}`); + } + } + resolve(basedir: string, path: string): E.Either { try { const result = resolve.sync(path, { @@ -82,12 +130,12 @@ export class Project { extensions: ['.ts', '.js'], }); return E.right(result); - } catch (e: any) { - if (typeof e === 'object' && e.hasOwnProperty('message')) { + } catch (e: unknown) { + if (e instanceof Error && e.message) { return E.left(e.message); - } else { - return E.left(JSON.stringify(e)); } + + return E.left(JSON.stringify(e)); } } @@ -95,4 +143,8 @@ export class Project { const baseKey = path.startsWith('.') ? '.' : path; return this.knownImports[baseKey]?.[name]; } + + getTypes() { + return this.types; + } } diff --git a/packages/openapi-generator/src/ref.ts b/packages/openapi-generator/src/ref.ts index aadfa57a..5e10ca4e 100644 --- a/packages/openapi-generator/src/ref.ts +++ b/packages/openapi-generator/src/ref.ts @@ -1,24 +1,34 @@ import type { Schema, Reference } from './ir'; +import fs from 'fs'; -export function getRefs(schema: Schema): Reference[] { +export function getRefs(schema: Schema, typeMap: Record): Reference[] { if (schema.type === 'ref') { + if (!fs.existsSync(schema.location)) { + // The location is a node module - we need to populate the location here + const newPath = typeMap[schema.name]; + if (!newPath) { + return []; + } + + return [{ ...schema, location: newPath }]; + } return [schema]; } else if (schema.type === 'array') { - return getRefs(schema.items); + return getRefs(schema.items, typeMap); } else if ( schema.type === 'intersection' || schema.type === 'union' || schema.type === 'tuple' ) { return schema.schemas.reduce((acc, member) => { - return [...acc, ...getRefs(member)]; + return [...acc, ...getRefs(member, typeMap)]; }, []); } else if (schema.type === 'object') { return Object.values(schema.properties).reduce((acc, member) => { - return [...acc, ...getRefs(member)]; + return [...acc, ...getRefs(member, typeMap)]; }, []); } else if (schema.type === 'record') { - return getRefs(schema.codomain); + return getRefs(schema.codomain, typeMap); } else { return []; } diff --git a/packages/openapi-generator/src/resolveInit.ts b/packages/openapi-generator/src/resolveInit.ts index 243d4d8f..6c254b22 100644 --- a/packages/openapi-generator/src/resolveInit.ts +++ b/packages/openapi-generator/src/resolveInit.ts @@ -13,7 +13,13 @@ function resolveImportPath( sourceFile: SourceFile, path: string, ): E.Either { - const importPathE = project.resolve(dirname(sourceFile.path), path); + let importPathE; + if (path.startsWith('.')) { + importPathE = project.resolve(dirname(sourceFile.path), path); + } else { + importPathE = project.resolveEntryPoint(dirname(sourceFile.path), path); + } + if (E.isLeft(importPathE)) { return importPathE; } diff --git a/packages/openapi-generator/src/sourceFile.ts b/packages/openapi-generator/src/sourceFile.ts index e72d11a4..3b375c16 100644 --- a/packages/openapi-generator/src/sourceFile.ts +++ b/packages/openapi-generator/src/sourceFile.ts @@ -14,7 +14,10 @@ export type SourceFile = { // increasing counter for this, so we also need to track it globally here let lastSpanEnd = -1; -export async function parseSource(path: string, src: string): Promise { +export async function parseSource( + path: string, + src: string, +): Promise { try { const module = await swc.parse(src, { syntax: 'typescript', @@ -34,8 +37,8 @@ export async function parseSource(path: string, src: string): Promise { - const project = new TestProject(files); + const project = new TestProject({ ...files, ...MOCK_NODE_MODULES_DIR }); await project.parseEntryPoint(entryPoint); const sourceFile = project.get(entryPoint); @@ -288,5 +289,5 @@ const MISSING_REFERENCE = { }; testCase('missing reference', MISSING_REFERENCE, '/index.ts', {}, [ - "Cannot find 'Foo' from 'foo'", + "Cannot find module 'foo' in the project", ]); diff --git a/packages/openapi-generator/test/externalModule.test.ts b/packages/openapi-generator/test/externalModule.test.ts new file mode 100644 index 00000000..38efa569 --- /dev/null +++ b/packages/openapi-generator/test/externalModule.test.ts @@ -0,0 +1,196 @@ +import * as E from 'fp-ts/lib/Either'; +import assert from 'node:assert/strict'; +import test from 'node:test'; +import * as p from 'path'; + +import { parsePlainInitializer, Project, type Schema } from '../src'; +import { KNOWN_IMPORTS } from '../src/knownImports'; + +/** External library parsing test case + * + * @param description a description of the test case + * @param entryPoint relative path to the test case's index.tx + * @param expected a record of expected files (including ones in node_modules), with their expected parsed schemas + * @param expectedErrors optional record of expected parsing errors for each source file + */ +async function testCase( + description: string, + entryPoint: string, + expected: Record>, + expectedErrors: Record = {}, +) { + test(description, async () => { + const project = new Project({}, KNOWN_IMPORTS); + const entryPointPath = p.resolve(entryPoint); + await project.parseEntryPoint(entryPointPath); + + for (const path of Object.keys(expected)) { + const resolvedPath = p.resolve(path); + const sourceFile = project.get(resolvedPath); + + if (sourceFile === undefined) { + throw new Error(`Source file ${path} not found`); + } + + const actual: Record = {}; + const errors: string[] = []; + for (const symbol of sourceFile.symbols.declarations) { + if (symbol.init !== undefined) { + const result = parsePlainInitializer(project, sourceFile, symbol.init); + if (E.isLeft(result)) { + errors.push(result.left); + } else { + if (symbol.comment !== undefined) { + result.right.comment = symbol.comment; + } + actual[symbol.name] = result.right; + } + } + } + + assert.deepEqual(actual, expected[path]); + assert.deepEqual(errors, expectedErrors[path] ?? []); + } + + // If we are expecting errors in a file that wasn't parsed, raise that here + for (const path of Object.keys(expectedErrors)) { + const resolvedPath = p.resolve(path); + assert.notEqual( + project.get(resolvedPath), + undefined, + `Expected errors for ${path} but it wasn't parsed`, + ); + } + }); +} + +const FoobarObject: Schema = { + type: 'object', + properties: { + foo: { + type: 'string', + }, + bar: { + type: 'number', + }, + }, + required: ['foo', 'bar'], +}; + +const RandomTypeObject: Schema = { + type: 'object', + properties: { + random: { + type: 'string', + }, + type: { + type: 'number', + }, + }, + required: ['random', 'type'], +}; + +const FOO_Object = (testNum: number): Schema => ({ + type: 'object', + properties: { + foobar: { + location: '@bitgo/foobar' + testNum, + name: 'Foobar', + type: 'ref', + }, + }, + required: ['foobar'], +}); + +const RANDOM_Object = (testNum: number): Schema => ({ + type: 'object', + properties: { + random: { + location: '@bitgo/random-types' + testNum, + name: 'RandomType', + type: 'ref', + }, + }, + required: ['random'], +}); + +testCase( + 'type from correctly formatted external library with export declaration', + 'test/sample-types/exportDeclaration.ts', + { + 'test/sample-types/exportDeclaration.ts': { + FOO: FOO_Object(1), + RANDOM: RANDOM_Object(1), + }, + 'test/sample-types/node_modules/@bitgo/foobar1/src/index.ts': { + Foobar: FoobarObject, + }, + 'test/sample-types/node_modules/@bitgo/random-types1/src/index.ts': { + RandomType: RandomTypeObject, + }, + }, +); + +testCase( + 'type from correctly formatted external library with export star declaration', + 'test/sample-types/exportStar.ts', + { + 'test/sample-types/exportStar.ts': { + FOO: FOO_Object(2), + RANDOM: RANDOM_Object(2), + }, + 'test/sample-types/node_modules/@bitgo/foobar2/src/foobar.ts': { + Foobar: FoobarObject, + }, + 'test/sample-types/node_modules/@bitgo/random-types2/src/randomType.ts': { + RandomType: RandomTypeObject, + }, + }, +); + +testCase( + 'type from correctly formatted external library with export star declaration and import star declaration', + 'test/sample-types/importStar.ts', + { + 'test/sample-types/importStar.ts': { + FOO: FOO_Object(4), + RANDOM: RANDOM_Object(4), + }, + 'test/sample-types/node_modules/@bitgo/foobar4/src/foobar.ts': { + Foobar: FoobarObject, + }, + 'test/sample-types/node_modules/@bitgo/random-types4/src/randomType.ts': { + RandomType: RandomTypeObject, + }, + }, +); + +testCase( + 'type from external library with syntax errors', + 'test/sample-types/syntaxError.ts', + { + 'test/sample-types/syntaxError.ts': { + FOO: FOO_Object(5), + }, + 'test/sample-types/node_modules/@bitgo/foobar5/src/foobar.ts': {}, + }, + { + 'test/sample-types/node_modules/@bitgo/foobar5/src/foobar.ts': [ + 'Unknown identifier ttype', + ], + }, +); + +testCase( + 'type from external library with import path error', + 'test/sample-types/importPathError.ts', + {}, + {}, +); + +testCase( + 'type from external library with export path error', + 'test/sample-types/exportPathError.ts', + {}, + {}, +); diff --git a/packages/openapi-generator/test/externalModuleApiSpec.test.ts b/packages/openapi-generator/test/externalModuleApiSpec.test.ts new file mode 100644 index 00000000..05c37e64 --- /dev/null +++ b/packages/openapi-generator/test/externalModuleApiSpec.test.ts @@ -0,0 +1,321 @@ +import assert from 'assert'; +import test from 'node:test'; +import { version } from 'typescript'; +import { + Project, + Route, + parseApiSpec, + Schema, + getRefs, + parseCodecInitializer, + convertRoutesToOpenAPI, +} from '../src'; +import { KNOWN_IMPORTS } from '../src/knownImports'; +import { findSymbolInitializer } from '../src/resolveInit'; +import * as p from 'path'; +import * as E from 'fp-ts/Either'; + +/** External library parsing and api spec generation test case + * + * + * @param description a description of the test case + * @param entryPoint the entrypoint of the api spec + * @param expected an open api spec object + * @param expectedErrors opetional record of expected parsing errors + */ +async function testCase( + description: string, + entryPoint: string, + expected: Record, + expectedErrors: string[] = [], +) { + test(description, async () => { + const project = new Project({}, KNOWN_IMPORTS); + const entryPointPath = p.resolve(entryPoint); + await project.parseEntryPoint(entryPointPath); + + const sourceFile = project.get(entryPointPath); + + if (sourceFile === undefined) { + throw new Error(`could not find source file ${entryPoint}`); + } + + const actual: Record = {}; + const errors: string[] = []; + + for (const symbol of sourceFile.symbols.declarations) { + if (symbol.init !== undefined) { + if (symbol.init.type !== 'CallExpression') { + continue; + } else if ( + symbol.init.callee.type !== 'MemberExpression' || + symbol.init.callee.property.type !== 'Identifier' || + symbol.init.callee.property.value !== 'apiSpec' + ) { + continue; + } else if (symbol.init.arguments.length !== 1) { + continue; + } + const arg = symbol.init.arguments[0]!; + if (arg.expression.type !== 'ObjectExpression') { + continue; + } + const result = parseApiSpec(project, sourceFile, arg.expression); + if (E.isLeft(result)) { + errors.push(result.left); + } else { + actual[symbol.name] = result.right; + } + } + } + + const apiSpec = Object.values(actual).flatMap((routes) => routes); + + const components: Record = {}; + const queue: Schema[] = apiSpec.flatMap((route) => { + return [ + ...route.parameters.map((p) => p.schema), + ...(route.body !== undefined ? [route.body] : []), + ...Object.values(route.response), + ]; + }); + let schema: Schema | undefined; + while (((schema = queue.pop()), schema !== undefined)) { + const refs = getRefs(schema, project.getTypes()); + for (const ref of refs) { + if (components[ref.name] !== undefined) { + continue; + } + const sourceFile = project.get(ref.location); + if (sourceFile === undefined) { + errors.push(`Could not find '${ref.name}' from '${ref.location}'`); + break; + } + + const initE = findSymbolInitializer(project, sourceFile, ref.name); + if (E.isLeft(initE)) { + errors.push( + `Could not find symbol '${ref.name}' in '${ref.location}': ${initE.left}`, + ); + break; + } + const [newSourceFile, init] = initE.right; + + const codecE = parseCodecInitializer(project, newSourceFile, init); + if (E.isLeft(codecE)) { + errors.push( + `Could not parse codec '${ref.name}' in '${ref.location}': ${codecE.left}`, + ); + break; + } + components[ref.name] = codecE.right; + queue.push(codecE.right); + } + } + + const name = description; + + const openapi = convertRoutesToOpenAPI( + { + title: name, + version, + description, + }, + [], + apiSpec, + components, + ); + + assert.deepEqual(errors, expectedErrors); + assert.deepEqual(openapi, expected); + }); +} + +testCase( + 'simple api spec with imported types', + 'test/sample-types/apiSpec.ts', + { + openapi: '3.0.3', + info: { + title: 'simple api spec with imported types', + version: '4.7.4', + description: 'simple api spec with imported types', + }, + paths: { + '/test': { + post: { + parameters: [], + requestBody: { + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + path1: { + type: 'string', + }, + path2: { + type: 'number', + }, + path3: { + type: 'boolean', + }, + path4: { + type: 'string', + enum: ['literal'], + }, + }, + required: ['path1', 'path2', 'path3', 'path4'], + }, + }, + }, + }, + responses: { + '200': { + description: 'OK', + content: { + 'application/json': { + schema: { + type: 'string', + }, + }, + }, + }, + }, + }, + get: { + parameters: [], + responses: { + '200': { + description: 'OK', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/SampleGetResponse', + }, + }, + }, + }, + }, + }, + }, + }, + components: { + schemas: { + SampleGetResponse: { + title: 'SampleGetResponse', + type: 'object', + properties: { + response1: { + type: 'string', + }, + response2: { + type: 'object', + properties: { + nested1: { + type: 'number', + }, + nested2: { + type: 'boolean', + }, + }, + required: ['nested1', 'nested2'], + }, + }, + required: ['response1', 'response2'], + }, + }, + }, + }, + [], +); + +testCase( + 'simple api spec with exported enum', + 'test/sample-types/apiSpecWithEnum.ts', + { + openapi: '3.0.3', + info: { + title: 'simple api spec with exported enum', + version: '4.7.4', + description: 'simple api spec with exported enum', + }, + paths: { + '/test': { + get: { + parameters: [], + responses: { + '200': { + description: 'OK', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/SampleEnumType', + }, + }, + }, + }, + }, + }, + }, + }, + components: { + schemas: { + SampleEnumType: { + title: 'SampleEnumType', + type: 'string', + enum: ['Value1', 'Value2'], + }, + }, + }, + }, + [], +); + +testCase( + 'simple api spec with exported union type', + 'test/sample-types/apiSpecWithUnion.ts', + { + openapi: "3.0.3", + info: { + title: "simple api spec with exported union type", + version: "4.7.4", + description: "simple api spec with exported union type" + }, + paths: { + "/test": { + get: { + parameters: [], + responses: { + 200: { + description: "OK", + content: { + 'application/json': { + schema: { + $ref: "#/components/schemas/SampleUnion" + } + } + } + } + } + } + } + }, + components: { + schemas: { + SampleUnion: { + title: "SampleUnion", + oneOf: [ + { + type: "string" + }, + { + type: "number" + } + ] + } + } + } + }, + [] +) diff --git a/packages/openapi-generator/test/externalModules.ts b/packages/openapi-generator/test/externalModules.ts new file mode 100644 index 00000000..e167c376 --- /dev/null +++ b/packages/openapi-generator/test/externalModules.ts @@ -0,0 +1,45 @@ +const IO_TS_CONTENTS = ` +export const type = (props: any) => ({ type: 'object', ...props }); +export const string = { type: 'string' }; +export const number = { type: 'number' }; +export const union = (schemas: any[]) => ({ type: 'union', schemas }); +export const keyof = (keys: any) => ({ type: 'union', schemas: Object.keys(keys).map((key) => ({ type: 'string', enum: [key] })) }); +export const literal = (value: any) => ({ type: typeof value, enum: [value] }); +`; + +const IO_TS_PACKAGE_JSON = `{ + "name": "io-ts", + "version": "1.0.0", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts" +}`; + +const IO_TS_HTTP_PACKAGE_JSON = `{ + "name": "@api-ts/io-ts-http", + "version": "1.0.0", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts" +}`; + +export const MOCK_NODE_MODULES_DIR = { + '/node_modules': { + '/@api-ts': { + '/io-ts-http': { + '/dist': { + '/src': { + '/index.js': ``, + }, + }, + '/package.json': IO_TS_HTTP_PACKAGE_JSON, + }, + }, + '/io-ts': { + '/dist': { + '/src': { + '/index.js': IO_TS_CONTENTS, + }, + }, + '/package.json': IO_TS_PACKAGE_JSON, + }, + }, +}; diff --git a/packages/openapi-generator/test/openapi.test.ts b/packages/openapi-generator/test/openapi.test.ts index 150d4afc..33551a94 100644 --- a/packages/openapi-generator/test/openapi.test.ts +++ b/packages/openapi-generator/test/openapi.test.ts @@ -21,6 +21,9 @@ async function testCase( ) { test(description, async () => { const sourceFile = await parseSource('./index.ts', src); + if (sourceFile === undefined) { + throw new Error('Failed to parse source file'); + } const project = new Project(); const routes: Route[] = []; diff --git a/packages/openapi-generator/test/project.test.ts b/packages/openapi-generator/test/project.test.ts index b1046853..60bebb2a 100644 --- a/packages/openapi-generator/test/project.test.ts +++ b/packages/openapi-generator/test/project.test.ts @@ -93,3 +93,29 @@ testCase( }, }, ); + +const NON_STRICT_MODE_SRC = ` +import * as t from 'io-ts'; +import { bar } from './bar'; +var static: serveStatic.RequestHandlerConstructor; +export const FOO = t.type({ bar: bar }); +`; + +test('non-strict files are ignored and logged to stderr', async () => { + let errorCalled = false; + const originalConsoleError = console.error; + + console.error = (...args) => { + errorCalled = true; + console.error = originalConsoleError; + const errorRegex = /Error parsing source file: \/index.ts/; + assert(errorRegex.test(args[0])); + }; + + const project = new TestProject({ '/index.ts': NON_STRICT_MODE_SRC }, {}); + await project.parseEntryPoint('/index.ts'); + const sourceFile = project.get('/index.ts'); + + assert.strictEqual(sourceFile, undefined); + assert.strictEqual(errorCalled, true, new Error('console.error was not called')); +}); diff --git a/packages/openapi-generator/test/ref.test.ts b/packages/openapi-generator/test/ref.test.ts index d69f4dae..93310b75 100644 --- a/packages/openapi-generator/test/ref.test.ts +++ b/packages/openapi-generator/test/ref.test.ts @@ -3,6 +3,11 @@ import test from 'node:test'; import { getRefs, type Schema } from '../src'; +const typeMap: Record = { + Foo: '/foo.ts', + Bar: '/bar.ts', +}; + test('simple ref is returned', () => { const schema: Schema = { type: 'ref', @@ -10,7 +15,7 @@ test('simple ref is returned', () => { location: '/foo.ts', }; - assert.deepEqual(getRefs(schema), [schema]); + assert.deepEqual(getRefs(schema, typeMap), [schema]); }); test('array ref is returned', () => { @@ -23,7 +28,7 @@ test('array ref is returned', () => { }, }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', @@ -49,7 +54,7 @@ test('intersection ref is returned', () => { ], }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', @@ -80,7 +85,7 @@ test('union ref is returned', () => { ], }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', @@ -111,7 +116,7 @@ test('tuple ref is returned', () => { ], }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', @@ -143,7 +148,7 @@ test('object ref is returned', () => { required: ['foo', 'bar'], }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', @@ -167,7 +172,7 @@ test('record ref is returned', () => { }, }; - assert.deepEqual(getRefs(schema), [ + assert.deepEqual(getRefs(schema, typeMap), [ { type: 'ref', name: 'Foo', diff --git a/packages/openapi-generator/test/resolve.test.ts b/packages/openapi-generator/test/resolve.test.ts index 924c9444..fe11bddb 100644 --- a/packages/openapi-generator/test/resolve.test.ts +++ b/packages/openapi-generator/test/resolve.test.ts @@ -5,6 +5,7 @@ import test from 'node:test'; import { TestProject } from './testProject'; import { parseCodecInitializer, Project, type Schema } from '../src'; +import { MOCK_NODE_MODULES_DIR } from './externalModules'; async function testCase( description: string, @@ -14,7 +15,7 @@ async function testCase( expectedErrors: string[] = [], ) { test(description, async () => { - let project: Project = new TestProject(files); + let project: Project = new TestProject({ ...files, ...MOCK_NODE_MODULES_DIR }); const projectE = await project.parseEntryPoint(entryPoint); if (E.isLeft(projectE)) { throw new Error(projectE.left); @@ -55,7 +56,9 @@ export const FOO = t.type(fooProps); testCase( 'const props initializer is parsed', - { '/index.ts': OBJECT_CONST }, + { + '/index.ts': OBJECT_CONST, + }, '/index.ts', { FOO: { @@ -75,7 +78,9 @@ export const FOO = t.union(fooUnion); testCase( 'const array initializer is parsed', - { '/index.ts': ARRAY_CONST }, + { + '/index.ts': ARRAY_CONST, + }, '/index.ts', { FOO: { @@ -97,7 +102,9 @@ export const FOO = t.keyof(fooKeys); testCase( 'const keyof initializer is parsed', - { '/index.ts': KEYOF_CONST }, + { + '/index.ts': KEYOF_CONST, + }, '/index.ts', { FOO: { @@ -119,7 +126,9 @@ export const FOO = t.literal(foo); testCase( 'const literal initializer is parsed', - { '/index.ts': LITERAL_CONST }, + { + '/index.ts': LITERAL_CONST, + }, '/index.ts', { FOO: { type: 'number', enum: [42] }, diff --git a/packages/openapi-generator/test/sample-types/.gitignore b/packages/openapi-generator/test/sample-types/.gitignore new file mode 100644 index 00000000..efdac649 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/.gitignore @@ -0,0 +1,2 @@ +!node_modules +!dist \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/apiSpec.ts b/packages/openapi-generator/test/sample-types/apiSpec.ts new file mode 100644 index 00000000..420e3738 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/apiSpec.ts @@ -0,0 +1,28 @@ +import { SamplePostRequest, SampleGetResponse } from '@bitgo/test-types'; +import * as t from 'io-ts'; +import * as h from '@api-ts/io-ts-http'; + +export const test = h.apiSpec({ + 'api.post.test': { + post: h.httpRoute({ + path: '/test', + method: 'POST', + request: h.httpRequest({ + body: SamplePostRequest, + }), + response: { + 200: t.string, + }, + }), + }, + 'api.get.test': { + get: h.httpRoute({ + path: '/test', + method: 'GET', + request: h.httpRequest({}), + response: { + 200: SampleGetResponse, + }, + }), + }, +}); diff --git a/packages/openapi-generator/test/sample-types/apiSpecWithEnum.ts b/packages/openapi-generator/test/sample-types/apiSpecWithEnum.ts new file mode 100644 index 00000000..ad1897aa --- /dev/null +++ b/packages/openapi-generator/test/sample-types/apiSpecWithEnum.ts @@ -0,0 +1,15 @@ +import { SampleEnumType } from '@bitgo/test-types'; +import * as h from '@api-ts/io-ts-http'; + +export const enumTest = h.apiSpec({ + 'api.get.test': { + get: h.httpRoute({ + path: '/test', + method: 'GET', + request: h.httpRequest({}), + response: { + 200: SampleEnumType, + }, + }), + }, +}); diff --git a/packages/openapi-generator/test/sample-types/apiSpecWithUnion.ts b/packages/openapi-generator/test/sample-types/apiSpecWithUnion.ts new file mode 100644 index 00000000..46985559 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/apiSpecWithUnion.ts @@ -0,0 +1,15 @@ +import { SampleUnion } from '@bitgo/test-types'; +import * as h from '@api-ts/io-ts-http'; + +export const enumTest = h.apiSpec({ + 'api.get.test': { + get: h.httpRoute({ + path: '/test', + method: 'GET', + request: h.httpRequest({}), + response: { + 200: SampleUnion, + }, + }), + }, +}); diff --git a/packages/openapi-generator/test/sample-types/exportDeclaration.ts b/packages/openapi-generator/test/sample-types/exportDeclaration.ts new file mode 100644 index 00000000..998957c4 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/exportDeclaration.ts @@ -0,0 +1,10 @@ +import { Foobar } from '@bitgo/foobar1'; +import { RandomType } from '@bitgo/random-types1'; + +export const FOO = { + foobar: Foobar, +}; + +export const RANDOM = { + random: RandomType, +}; diff --git a/packages/openapi-generator/test/sample-types/exportPathError.ts b/packages/openapi-generator/test/sample-types/exportPathError.ts new file mode 100644 index 00000000..78ccfcd6 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/exportPathError.ts @@ -0,0 +1,5 @@ +import * as f from '@bitgo/foobar6'; + +export const FOO = { + foobar: f.foobar, +}; diff --git a/packages/openapi-generator/test/sample-types/exportStar.ts b/packages/openapi-generator/test/sample-types/exportStar.ts new file mode 100644 index 00000000..e8facaac --- /dev/null +++ b/packages/openapi-generator/test/sample-types/exportStar.ts @@ -0,0 +1,10 @@ +import { Foobar } from '@bitgo/foobar2'; +import { RandomType } from '@bitgo/random-types2'; + +export const FOO = { + foobar: Foobar, +}; + +export const RANDOM = { + random: RandomType, +}; diff --git a/packages/openapi-generator/test/sample-types/importPathError.ts b/packages/openapi-generator/test/sample-types/importPathError.ts new file mode 100644 index 00000000..9a73f99a --- /dev/null +++ b/packages/openapi-generator/test/sample-types/importPathError.ts @@ -0,0 +1,5 @@ +import * as f from '@bitgo/foobar3'; + +export const FOO = { + foobar: f.Foobar, +}; diff --git a/packages/openapi-generator/test/sample-types/importStar.ts b/packages/openapi-generator/test/sample-types/importStar.ts new file mode 100644 index 00000000..07db6e1b --- /dev/null +++ b/packages/openapi-generator/test/sample-types/importStar.ts @@ -0,0 +1,10 @@ +import * as f from '@bitgo/foobar4'; +import * as r from '@bitgo/random-types4'; + +export const FOO = { + foobar: f.Foobar, +}; + +export const RANDOM = { + random: r.RandomType, +}; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/package.json new file mode 100644 index 00000000..7cdf2f85 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar1", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/src/index.ts new file mode 100644 index 00000000..2f9b87a5 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/src/index.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const Foobar = t.type({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar1/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/package.json new file mode 100644 index 00000000..4f4bea28 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar2", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/foobar.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/foobar.ts new file mode 100644 index 00000000..2f9b87a5 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/foobar.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const Foobar = t.type({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/index.ts new file mode 100644 index 00000000..8c0467ec --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/src/index.ts @@ -0,0 +1 @@ +export * from './foobar'; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar2/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/package.json new file mode 100644 index 00000000..f4fa0295 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar3", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/foobar.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/foobar.ts new file mode 100644 index 00000000..bfa05275 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/foobar.ts @@ -0,0 +1,6 @@ +import * as t from 'io-tsg' // This type is intentional, don't fix + +export const Foobar = t.type({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/index.ts new file mode 100644 index 00000000..8c0467ec --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/src/index.ts @@ -0,0 +1 @@ +export * from './foobar'; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/tsconfig.json new file mode 100644 index 00000000..128699bc --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar3/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/package.json new file mode 100644 index 00000000..a74e6ae1 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar4", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/foobar.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/foobar.ts new file mode 100644 index 00000000..2f9b87a5 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/foobar.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const Foobar = t.type({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/index.ts new file mode 100644 index 00000000..8c0467ec --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/src/index.ts @@ -0,0 +1 @@ +export * from './foobar'; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/tsconfig.json new file mode 100644 index 00000000..128699bc --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar4/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/package.json new file mode 100644 index 00000000..07ab5586 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar5", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/foobar.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/foobar.ts new file mode 100644 index 00000000..935f3328 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/foobar.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const Foobar = ttype({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/index.ts new file mode 100644 index 00000000..8c0467ec --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/src/index.ts @@ -0,0 +1 @@ +export * from './foobar'; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/tsconfig.json new file mode 100644 index 00000000..128699bc --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar5/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/package.json new file mode 100644 index 00000000..dac77093 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/package.json @@ -0,0 +1,16 @@ +{ + "name": "foobar6", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/foobar.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/foobar.ts new file mode 100644 index 00000000..2f9b87a5 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/foobar.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const Foobar = t.type({ + foo: t.string, + bar: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/index.ts new file mode 100644 index 00000000..bce948dd --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/src/index.ts @@ -0,0 +1,2 @@ +export * from './foobart'; // This typo is intentional, don't fix +export const foobar = 'foobar'; \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/tsconfig.json new file mode 100644 index 00000000..128699bc --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/foobar6/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/package.json new file mode 100644 index 00000000..88826e9e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/package.json @@ -0,0 +1,16 @@ +{ + "name": "random-types1", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/src/index.ts new file mode 100644 index 00000000..946e37fd --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/src/index.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const RandomType = t.type({ + random: t.string, + type: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types1/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/package.json new file mode 100644 index 00000000..d825ae69 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/package.json @@ -0,0 +1,16 @@ +{ + "name": "random-types2", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/index.ts new file mode 100644 index 00000000..586e0257 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/index.ts @@ -0,0 +1,2 @@ +export * from './randomType'; + diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/randomType.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/randomType.ts new file mode 100644 index 00000000..946e37fd --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/src/randomType.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const RandomType = t.type({ + random: t.string, + type: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types2/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/package.json new file mode 100644 index 00000000..d8d3ae81 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/package.json @@ -0,0 +1,16 @@ +{ + "name": "random-types4", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/index.ts new file mode 100644 index 00000000..ed5c4aec --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/index.ts @@ -0,0 +1 @@ +export * from './randomType'; diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/randomType.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/randomType.ts new file mode 100644 index 00000000..946e37fd --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/src/randomType.ts @@ -0,0 +1,6 @@ +import * as t from 'io-ts' + +export const RandomType = t.type({ + random: t.string, + type: t.number, +}); \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/random-types4/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/dist/src/index.js b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/dist/src/index.js new file mode 100644 index 00000000..e69de29b diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/dist/src/index.js.map b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/dist/src/index.js.map new file mode 100644 index 00000000..a84c1a88 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/dist/src/index.js.map @@ -0,0 +1,3 @@ +{ + "sources": ["../../src/index.ts"] +} \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/package.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/package.json new file mode 100644 index 00000000..e5df2e18 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/package.json @@ -0,0 +1,16 @@ +{ + "name": "test-types", + "version": "0.0.1", + "main": "dist/src/index.js", + "types": "src/index.ts", + "files": [ + "dist/src/**/*", + "src/**/*" + ], + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/src/index.ts b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/src/index.ts new file mode 100644 index 00000000..9bff5aa3 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/src/index.ts @@ -0,0 +1,26 @@ +import * as t from 'io-ts'; + +export const SamplePostRequest = { + path1: t.string, + path2: t.number, + path3: t.boolean, + path4: t.literal('literal'), +}; + +export const SampleGetResponse = t.type({ + response1: t.string, + response2: t.type({ + nested1: t.number, + nested2: t.boolean, + }) +}); + +export enum SampleEnum { + Value1 = 'value1', + Value2 = 'value2', +} + +export const SampleEnumType = t.keyof(SampleEnum, "SampleEnum"); +export type SampleEnumType = t.TypeOf; + +export const SampleUnion = t.union([t.string, t.number]); diff --git a/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/tsconfig.json b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/tsconfig.json new file mode 100644 index 00000000..6673fe4e --- /dev/null +++ b/packages/openapi-generator/test/sample-types/node_modules/@bitgo/test-types/tsconfig.json @@ -0,0 +1,7 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "outDir": "dist" + }, + "references": [] + } \ No newline at end of file diff --git a/packages/openapi-generator/test/sample-types/syntaxError.ts b/packages/openapi-generator/test/sample-types/syntaxError.ts new file mode 100644 index 00000000..4703e359 --- /dev/null +++ b/packages/openapi-generator/test/sample-types/syntaxError.ts @@ -0,0 +1,5 @@ +import * as f from '@bitgo/foobar5'; + +export const FOO = { + foobar: f.Foobar, +}; diff --git a/packages/openapi-generator/tsconfig.json b/packages/openapi-generator/tsconfig.json index c1d8b5bb..42beba8f 100644 --- a/packages/openapi-generator/tsconfig.json +++ b/packages/openapi-generator/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "include": ["src/**/*.ts", "test/**/*.json", "test/**/*.ts"], + "exclude": ["test/sample-types/**/*"], "compilerOptions": { "outDir": "dist" },