diff --git a/packages/openapi-python/src/config/init.ts b/packages/openapi-python/src/config/init.ts index 448883dd9..1c9c870c8 100644 --- a/packages/openapi-python/src/config/init.ts +++ b/packages/openapi-python/src/config/init.ts @@ -1,12 +1,12 @@ import type { Logger } from '@hey-api/codegen-core'; import { loadConfigFile } from '@hey-api/codegen-core'; -// import { expandToJobs } from './expand'; +import { expandToJobs } from './expand'; // import { getProjectDependencies } from './packages'; import type { ResolvedJob } from './resolve'; -// import { resolveConfig } from './resolve'; +import { resolveConfig } from './resolve'; import type { UserConfig } from './types'; -// import { validateJobs } from './validate'; +import { validateJobs } from './validate'; export type Configs = { dependencies: Record; @@ -38,12 +38,13 @@ export async function resolveJobs({ const loaded = await loadConfigFile({ configFile, logger, - name: 'openapi-ts', + name: 'openapi-python', userConfig, }); if (!Object.keys(dependencies).length) { // TODO: handle dependencies for multiple configs properly? + // TODO: collect Python dependencies // dependencies = getProjectDependencies( // loaded.foundConfig ? loaded.configFile : undefined, // ); @@ -54,15 +55,12 @@ export async function resolveJobs({ eventLoad.timeEnd(); const eventBuild = logger.timeEvent('build'); - // const jobs = validateJobs(expandToJobs(configs)); - // const resolvedJobs = jobs.map((validated) => - // resolveConfig(validated, dependencies), - // ); + const jobs = validateJobs(expandToJobs(configs)); + const resolvedJobs = jobs.map((validated) => resolveConfig(validated, dependencies)); eventBuild.timeEnd(); return { dependencies, - jobs: [], - // jobs: resolvedJobs, + jobs: resolvedJobs, }; } diff --git a/packages/openapi-python/src/config/output/postprocess.ts b/packages/openapi-python/src/config/output/postprocess.ts index 07dd53ffd..7ef3fc702 100644 --- a/packages/openapi-python/src/config/output/postprocess.ts +++ b/packages/openapi-python/src/config/output/postprocess.ts @@ -1,7 +1,36 @@ import type { PostProcessor } from '@hey-api/shared'; export const postProcessors = { - // TODO: add common post-processors + autopep8: { + args: ['--in-place', '{{path}}'], + command: 'autopep8', + name: 'autopep8', + }, + black: { + args: ['{{path}}'], + command: 'black', + name: 'Black', + }, + isort: { + args: ['{{path}}'], + command: 'isort', + name: 'isort', + }, + 'ruff:format': { + args: ['format', '{{path}}'], + command: 'ruff', + name: 'Ruff (Format)', + }, + 'ruff:lint': { + args: ['check', '--fix', '{{path}}'], + command: 'ruff', + name: 'Ruff (Lint)', + }, + yapf: { + args: ['-i', '{{path}}'], + command: 'yapf', + name: 'YAPF', + }, } as const satisfies Record; export type PostProcessorPreset = keyof typeof postProcessors; diff --git a/packages/openapi-python/src/config/output/types.ts b/packages/openapi-python/src/config/output/types.ts index 48611cdbe..30a471eb1 100644 --- a/packages/openapi-python/src/config/output/types.ts +++ b/packages/openapi-python/src/config/output/types.ts @@ -20,9 +20,8 @@ export type UserOutput = BaseUserOutput & { * * Use preset strings for common tools, or provide custom configurations. * - * @example ['biome:lint', 'prettier'] - * @example [{ command: 'dprint', args: ['fmt', '{{path}}'] }] - * @example ['eslint', { command: 'prettier', args: ['{{path}}', '--write'] }] + * @example ['ruff:lint', 'ruff:format'] + * @example [{ command: 'flake8', args: ['{{path}}'] }] * * @default [] */ diff --git a/packages/openapi-python/src/createClient.ts b/packages/openapi-python/src/createClient.ts index 879053836..945e5327a 100644 --- a/packages/openapi-python/src/createClient.ts +++ b/packages/openapi-python/src/createClient.ts @@ -20,7 +20,7 @@ import colors from 'ansi-colors'; import { postProcessors } from './config/output/postprocess'; import type { Config } from './config/types'; -// import { generateOutput } from './generate/output'; +import { generateOutput } from './generate/output'; // import { TypeScriptRenderer } from './ts-dsl'; export async function createClient({ @@ -143,7 +143,7 @@ export async function createClient({ eventParser.timeEnd(); const eventGenerator = logger.timeEvent('generator'); - // await generateOutput({ context }); + await generateOutput(context); eventGenerator.timeEnd(); const eventPostprocess = logger.timeEvent('postprocess'); diff --git a/packages/openapi-python/src/generate/output.ts b/packages/openapi-python/src/generate/output.ts new file mode 100644 index 000000000..9d699d58a --- /dev/null +++ b/packages/openapi-python/src/generate/output.ts @@ -0,0 +1,76 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import type { Context } from '@hey-api/shared'; +import { IntentContext } from '@hey-api/shared'; + +// import { getTypedConfig } from '../config/utils'; +// import { getClientPlugin } from '../plugins/@hey-api/client-core/utils'; +// import { generateClientBundle } from './client'; + +export async function generateOutput(context: Context): Promise { + const outputPath = path.resolve(context.config.output.path); + + if (context.config.output.clean) { + if (fs.existsSync(outputPath)) { + fs.rmSync(outputPath, { force: true, recursive: true }); + } + } + + // const config = getTypedConfig(context); + + // const client = getClientPlugin(config); + // if ('bundle' in client.config && client.config.bundle && !config.dryRun) { + // not proud of this one + // // @ts-expect-error + // config._FRAGILE_CLIENT_BUNDLE_RENAMED = generateClientBundle({ + // meta: { + // importFileExtension: config.output.importFileExtension, + // }, + // outputPath, + // // @ts-expect-error + // plugin: client, + // project: context.gen, + // }); + // } + + for (const plugin of context.registerPlugins()) { + await plugin.run(); + } + + context.gen.plan(); + + const ctx = new IntentContext(context.spec); + for (const intent of context.intents) { + await intent.run(ctx); + } + + for (const file of context.gen.render()) { + const filePath = path.resolve(outputPath, file.path); + const dir = path.dirname(filePath); + if (!context.config.dryRun) { + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(filePath, file.content, { encoding: 'utf8' }); + } + } + + const { source } = context.config.output; + if (source.enabled) { + const sourcePath = source.path === null ? undefined : path.resolve(outputPath, source.path); + if (!context.config.dryRun && sourcePath && sourcePath !== outputPath) { + fs.mkdirSync(sourcePath, { recursive: true }); + } + const serialized = await source.serialize(context.spec); + // TODO: handle yaml (convert before writing) + if (!context.config.dryRun && sourcePath) { + fs.writeFileSync( + path.resolve(sourcePath, `${source.fileName}.${source.extension}`), + serialized, + { encoding: 'utf8' }, + ); + } + if (source.callback) { + await source.callback(serialized); + } + } +} diff --git a/packages/openapi-python/src/plugins/@hey-api/sdk/config.ts b/packages/openapi-python/src/plugins/@hey-api/sdk/config.ts index b2a4e1d54..6e3617ae7 100644 --- a/packages/openapi-python/src/plugins/@hey-api/sdk/config.ts +++ b/packages/openapi-python/src/plugins/@hey-api/sdk/config.ts @@ -19,59 +19,50 @@ export const defaultConfig: HeyApiSdkPlugin['Config'] = { // eslint-disable-next-line sort-keys-fix/sort-keys-fix response: 'body', }, - dependencies: ['@hey-api/typescript'], handler, name: '@hey-api/python-sdk', - resolveConfig: (plugin, context) => { - if (plugin.config.client) { - if (typeof plugin.config.client === 'boolean') { - plugin.config.client = context.pluginByTag('client', { - defaultPlugin: '@hey-api/client-httpx', - }); - } - - plugin.dependencies.add(plugin.config.client!); - } else { - plugin.config.client = false; - } - - if (plugin.config.transformer) { - if (typeof plugin.config.transformer === 'boolean') { - plugin.config.transformer = context.pluginByTag('transformer'); - } - - plugin.dependencies.add(plugin.config.transformer!); - } else { - plugin.config.transformer = false; - } - - if (typeof plugin.config.validator !== 'object') { - plugin.config.validator = { - request: plugin.config.validator, - response: plugin.config.validator, - }; - } - - if (plugin.config.validator.request) { - if (typeof plugin.config.validator.request === 'boolean') { - plugin.config.validator.request = context.pluginByTag('validator'); - } - - plugin.dependencies.add(plugin.config.validator.request!); - } else { - plugin.config.validator.request = false; - } - - if (plugin.config.validator.response) { - if (typeof plugin.config.validator.response === 'boolean') { - plugin.config.validator.response = context.pluginByTag('validator'); - } - - plugin.dependencies.add(plugin.config.validator.response!); - } else { - plugin.config.validator.response = false; - } - + // resolveConfig: (plugin, context) => { + resolveConfig: () => { + // if (plugin.config.client) { + // if (typeof plugin.config.client === 'boolean') { + // plugin.config.client = context.pluginByTag('client', { + // defaultPlugin: '@hey-api/client-httpx', + // }); + // } + // plugin.dependencies.add(plugin.config.client!); + // } else { + // plugin.config.client = false; + // } + // if (plugin.config.transformer) { + // if (typeof plugin.config.transformer === 'boolean') { + // plugin.config.transformer = context.pluginByTag('transformer'); + // } + // plugin.dependencies.add(plugin.config.transformer!); + // } else { + // plugin.config.transformer = false; + // } + // if (typeof plugin.config.validator !== 'object') { + // plugin.config.validator = { + // request: plugin.config.validator, + // response: plugin.config.validator, + // }; + // } + // if (plugin.config.validator.request) { + // if (typeof plugin.config.validator.request === 'boolean') { + // plugin.config.validator.request = context.pluginByTag('validator'); + // } + // plugin.dependencies.add(plugin.config.validator.request!); + // } else { + // plugin.config.validator.request = false; + // } + // if (plugin.config.validator.response) { + // if (typeof plugin.config.validator.response === 'boolean') { + // plugin.config.validator.response = context.pluginByTag('validator'); + // } + // plugin.dependencies.add(plugin.config.validator.response!); + // } else { + // plugin.config.validator.response = false; + // } // plugin.config.examples = resolveExamples(plugin.config, context); // plugin.config.operations = resolveOperations(plugin.config, context); }, diff --git a/packages/openapi-ts/src/createClient.ts b/packages/openapi-ts/src/createClient.ts index 033755e9b..f0df68041 100644 --- a/packages/openapi-ts/src/createClient.ts +++ b/packages/openapi-ts/src/createClient.ts @@ -142,7 +142,7 @@ export async function createClient({ eventParser.timeEnd(); const eventGenerator = logger.timeEvent('generator'); - await generateOutput({ context }); + await generateOutput(context); eventGenerator.timeEnd(); const eventPostprocess = logger.timeEvent('postprocess'); diff --git a/packages/openapi-ts/src/generate/output.ts b/packages/openapi-ts/src/generate/output.ts index c18294eb1..03ce2da10 100644 --- a/packages/openapi-ts/src/generate/output.ts +++ b/packages/openapi-ts/src/generate/output.ts @@ -8,7 +8,7 @@ import { getTypedConfig } from '../config/utils'; import { getClientPlugin } from '../plugins/@hey-api/client-core/utils'; import { generateClientBundle } from './client'; -export const generateOutput = async ({ context }: { context: Context }) => { +export async function generateOutput(context: Context): Promise { const outputPath = path.resolve(context.config.output.path); if (context.config.output.clean) { @@ -73,4 +73,4 @@ export const generateOutput = async ({ context }: { context: Context }) => { await source.callback(serialized); } } -}; +}