Skip to content

Commit

Permalink
cli: Improve download of remote API specifications
Browse files Browse the repository at this point in the history
  • Loading branch information
karlvr committed Jan 31, 2024
1 parent dd11d24 commit dba625d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/mighty-cougars-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-generator-plus": minor
---

Improve download of remote API specifications
41 changes: 38 additions & 3 deletions packages/cli/src/generate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { promises as fs } from 'fs'
import { constructGenerator, createCodegenDocument, createCodegenState, createCodegenInput, createGeneratorContext } from '@openapi-generator-plus/core'
import { CodegenDocument, CodegenConfig, CodegenGeneratorConstructor } from '@openapi-generator-plus/types'
import { CodegenDocument, CodegenConfig, CodegenGeneratorConstructor, CodegenInputDocument } from '@openapi-generator-plus/types'
import getopts from 'getopts'
import path from 'path'
import { CommandLineOptions, CommandLineConfig } from './types'
Expand All @@ -18,13 +18,37 @@ function createMyGeneratorContext() {
})
}

async function createCodegenInputPossiblyWithUrl(inputPathOrUrl: string): Promise<CodegenInputDocument> {
if (isURL(inputPathOrUrl)) {
console.info(c.bold.green('Downloading:'), inputPathOrUrl)

const startTime = Date.now()
const response = await fetch(inputPathOrUrl)
const text = await response.text()
console.info(c.bold.green(`Downloaded in ${Date.now() - startTime}ms:`), inputPathOrUrl)

const tempDir = await fs.mkdtemp('openapi-generator-plus')
const tempFile = path.resolve(tempDir, path.basename(inputPathOrUrl) || 'openapi.yaml')
fs.writeFile(tempFile, text)

try {
return await createCodegenInput(tempFile)
} finally {
await fs.unlink(tempFile)
await fs.rmdir(tempDir)
}
} else {
return await createCodegenInput(inputPathOrUrl)
}
}

async function generate(config: CommandLineConfig, generatorConstructor: CodegenGeneratorConstructor): Promise<boolean> {
const generator = constructGenerator(config, createMyGeneratorContext(), generatorConstructor)

const state = createCodegenState(config, generator)
state.log = log
const input = await createCodegenInput(config.inputPath)


const input = await createCodegenInputPossiblyWithUrl(config.inputPath)
let doc: CodegenDocument
try {
doc = createCodegenDocument(input, state)
Expand Down Expand Up @@ -243,3 +267,14 @@ async function currentFilesystemTimestamp(outputPath: string): Promise<number> {
await fs.unlink(tempPath)
return stats.mtime.getTime()
}

/**
* Test whether the given string looks like a URL according to https://www.ietf.org/rfc/rfc1738.txt
* <p>
* Checks if the string starts with a valid scheme followed by a colon.
* @param value
* @returns
*/
function isURL(value: string): boolean {
return value.match(/^[a-zA-Z0-9+.-]+:/) !== null
}

0 comments on commit dba625d

Please sign in to comment.