@geekmidas/cli 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +119 -0
  2. package/dist/{OpenApiTsGenerator-0ZDYWro5.mjs → OpenApiTsGenerator-BVS4pOH7.mjs} +2 -2
  3. package/dist/{OpenApiTsGenerator-0ZDYWro5.mjs.map → OpenApiTsGenerator-BVS4pOH7.mjs.map} +1 -1
  4. package/dist/{OpenApiTsGenerator-wLwpaq_I.cjs → OpenApiTsGenerator-gPIIyppX.cjs} +2 -2
  5. package/dist/{OpenApiTsGenerator-wLwpaq_I.cjs.map → OpenApiTsGenerator-gPIIyppX.cjs.map} +1 -1
  6. package/dist/build/index.cjs +4 -4
  7. package/dist/build/index.mjs +4 -4
  8. package/dist/{build-BLriHKgm.mjs → build-Cu6Mi0Lf.mjs} +2 -2
  9. package/dist/{build-BLriHKgm.mjs.map → build-Cu6Mi0Lf.mjs.map} +1 -1
  10. package/dist/{build-Z3yGHcy2.cjs → build-wmt8ZcmA.cjs} +2 -2
  11. package/dist/{build-Z3yGHcy2.cjs.map → build-wmt8ZcmA.cjs.map} +1 -1
  12. package/dist/config-Bq72aj8e.mjs.map +1 -1
  13. package/dist/config-CFls09Ey.cjs.map +1 -1
  14. package/dist/config.d.cts +1 -1
  15. package/dist/config.d.mts +1 -1
  16. package/dist/dev/index.cjs +3 -3
  17. package/dist/dev/index.mjs +3 -3
  18. package/dist/{dev-BimlVcuk.mjs → dev-BBPWSllq.mjs} +2 -2
  19. package/dist/{dev-BimlVcuk.mjs.map → dev-BBPWSllq.mjs.map} +1 -1
  20. package/dist/{dev-Dcrb_ZSL.cjs → dev-C2lCgE53.cjs} +2 -2
  21. package/dist/{dev-Dcrb_ZSL.cjs.map → dev-C2lCgE53.cjs.map} +1 -1
  22. package/dist/generators/OpenApiTsGenerator.cjs +1 -1
  23. package/dist/generators/OpenApiTsGenerator.mjs +1 -1
  24. package/dist/index.cjs +5 -5
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.mjs +5 -5
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/{openapi-Dn9MeKg3.mjs → openapi-DA9RkPJl.mjs} +2 -2
  29. package/dist/{openapi-Dn9MeKg3.mjs.map → openapi-DA9RkPJl.mjs.map} +1 -1
  30. package/dist/{openapi-CTae4ybf.cjs → openapi-DZH6RQHk.cjs} +2 -2
  31. package/dist/{openapi-CTae4ybf.cjs.map → openapi-DZH6RQHk.cjs.map} +1 -1
  32. package/dist/openapi.cjs +2 -2
  33. package/dist/openapi.mjs +2 -2
  34. package/package.json +5 -5
  35. package/src/config.ts +1 -0
  36. package/src/dev/__tests__/index.spec.ts +6 -3
  37. package/src/generators/OpenApiTsGenerator.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["pkg","name: string | undefined","options: InitOptions","name","options: {\n provider?: string;\n providers?: string;\n enableOpenapi?: boolean;\n }","options: { port?: string; enableOpenapi?: boolean }","options: { output?: string; json?: boolean }","options: { input?: string; output?: string; name?: string }"],"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@geekmidas/cli\",\n \"version\": \"0.6.0\",\n \"description\": \"CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs\",\n \"private\": false,\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./config\": {\n \"types\": \"./dist/config.d.ts\",\n \"import\": \"./dist/config.mjs\",\n \"require\": \"./dist/config.cjs\"\n },\n \"./openapi\": {\n \"types\": \"./dist/openapi.d.ts\",\n \"import\": \"./dist/openapi.mjs\",\n \"require\": \"./dist/openapi.cjs\"\n },\n \"./openapi-react-query\": {\n \"types\": \"./dist/openapi-react-query.d.ts\",\n \"import\": \"./dist/openapi-react-query.mjs\",\n \"require\": \"./dist/openapi-react-query.cjs\"\n }\n },\n \"bin\": {\n \"gkm\": \"./dist/index.cjs\"\n },\n \"scripts\": {\n \"ts\": \"tsc --noEmit --skipLibCheck src/**/*.ts\",\n \"test\": \"vitest\",\n \"test:once\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/geekmidas/toolbox\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^10.1.0\",\n \"chokidar\": \"~4.0.3\",\n \"commander\": \"^12.1.0\",\n \"dotenv\": \"~17.2.3\",\n \"fast-glob\": \"^3.3.2\",\n \"lodash.kebabcase\": \"^4.1.1\",\n \"openapi-typescript\": \"^7.4.2\",\n \"prompts\": \"~2.4.2\"\n },\n \"devDependencies\": {\n \"@geekmidas/testkit\": \"workspace:*\",\n \"@types/lodash.kebabcase\": \"^4.1.9\",\n \"@types/node\": \"~24.9.1\",\n \"@types/prompts\": \"~2.4.9\",\n \"typescript\": \"^5.8.2\",\n \"vitest\": \"^3.2.4\",\n \"zod\": \"~4.1.13\"\n },\n \"peerDependencies\": {\n \"@geekmidas/constructs\": \"workspace:~\",\n \"@geekmidas/envkit\": \"workspace:~\",\n \"@geekmidas/logger\": \"workspace:~\",\n \"@geekmidas/schema\": \"workspace:~\",\n \"@geekmidas/telescope\": \"workspace:~\"\n },\n \"peerDependenciesMeta\": {\n \"@geekmidas/telescope\": {\n \"optional\": true\n }\n }\n}\n","#!/usr/bin/env -S npx tsx\n\nimport { Command } from 'commander';\nimport pkg from '../package.json' assert { type: 'json' };\nimport { buildCommand } from './build/index.ts';\nimport { devCommand } from './dev/index.ts';\nimport { type InitOptions, initCommand } from './init/index.ts';\nimport { generateReactQueryCommand } from './openapi-react-query.ts';\nimport { openapiCommand } from './openapi.ts';\nimport type { LegacyProvider, MainProvider } from './types.ts';\n\nconst program = new Command();\n\nprogram\n .name('gkm')\n .description('GeekMidas backend framework CLI')\n .version(pkg.version)\n .option('--cwd <path>', 'Change working directory');\n\nprogram\n .command('init')\n .description('Scaffold a new project')\n .argument('[name]', 'Project name')\n .option(\n '--template <template>',\n 'Project template (minimal, api, serverless, worker)',\n )\n .option('--skip-install', 'Skip dependency installation', false)\n .option('-y, --yes', 'Skip prompts, use defaults', false)\n .option('--monorepo', 'Setup as monorepo with packages/models', false)\n .option('--api-path <path>', 'API app path in monorepo (default: apps/api)')\n .action(async (name: string | undefined, options: InitOptions) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await initCommand(name, options);\n } catch (error) {\n console.error('Init failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('build')\n .description('Build handlers from endpoints, functions, and crons')\n .option(\n '--provider <provider>',\n 'Target provider for generated handlers (aws, server)',\n )\n .option(\n '--providers <providers>',\n '[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)',\n )\n .option(\n '--enable-openapi',\n 'Enable OpenAPI documentation generation for server builds',\n )\n .action(\n async (options: {\n provider?: string;\n providers?: string;\n enableOpenapi?: boolean;\n }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n\n // Handle new single provider option\n if (options.provider) {\n if (!['aws', 'server'].includes(options.provider)) {\n console.error(\n `Invalid provider: ${options.provider}. Must be 'aws' or 'server'.`,\n );\n process.exit(1);\n }\n await buildCommand({\n provider: options.provider as MainProvider,\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n // Handle legacy providers option\n else if (options.providers) {\n console.warn(\n '⚠️ --providers flag is deprecated. Use --provider instead.',\n );\n const providerList = [\n ...new Set(options.providers.split(',').map((p) => p.trim())),\n ] as LegacyProvider[];\n await buildCommand({\n providers: providerList,\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n // Default to config-driven build\n else {\n await buildCommand({\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n } catch (error) {\n console.error('Build failed:', (error as Error).message);\n process.exit(1);\n }\n },\n );\n\nprogram\n .command('dev')\n .description('Start development server with automatic reload')\n .option('--port <port>', 'Port to run the development server on', '3000')\n .option(\n '--enable-openapi',\n 'Enable OpenAPI documentation for development server',\n true,\n )\n .action(async (options: { port?: string; enableOpenapi?: boolean }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n\n await devCommand({\n port: options.port ? Number.parseInt(options.port) : 3000,\n enableOpenApi: options.enableOpenapi ?? true,\n });\n } catch (error) {\n console.error('Dev server failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('cron')\n .description('Manage cron jobs')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('Cron management - coming soon\\n');\n });\n\nprogram\n .command('function')\n .description('Manage serverless functions')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('Serverless function management - coming soon\\n');\n });\n\nprogram\n .command('api')\n .description('Manage REST API endpoints')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('REST API management - coming soon\\n');\n });\n\nprogram\n .command('openapi')\n .description(\n 'Generate OpenAPI specification from endpoints (TypeScript by default)',\n )\n .option(\n '--output <path>',\n 'Output file path for the OpenAPI spec',\n 'openapi.ts',\n )\n .option('--json', 'Generate JSON instead of TypeScript (legacy)', false)\n .action(async (options: { output?: string; json?: boolean }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await openapiCommand(options);\n } catch (error) {\n console.error('OpenAPI generation failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('generate:react-query')\n .description('Generate React Query hooks from OpenAPI specification')\n .option('--input <path>', 'Input OpenAPI spec file path', 'openapi.json')\n .option(\n '--output <path>',\n 'Output file path for generated hooks',\n 'src/api/hooks.ts',\n )\n .option('--name <name>', 'API name prefix for generated code', 'API')\n .action(\n async (options: { input?: string; output?: string; name?: string }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await generateReactQueryCommand(options);\n } catch (error) {\n console.error(\n 'React Query generation failed:',\n (error as Error).message,\n );\n process.exit(1);\n }\n },\n );\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["pkg","name: string | undefined","options: InitOptions","name","options: {\n provider?: string;\n providers?: string;\n enableOpenapi?: boolean;\n }","options: { port?: string; enableOpenapi?: boolean }","options: { output?: string; json?: boolean }","options: { input?: string; output?: string; name?: string }"],"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@geekmidas/cli\",\n \"version\": \"0.6.2\",\n \"description\": \"CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs\",\n \"private\": false,\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./config\": {\n \"types\": \"./dist/config.d.ts\",\n \"import\": \"./dist/config.mjs\",\n \"require\": \"./dist/config.cjs\"\n },\n \"./openapi\": {\n \"types\": \"./dist/openapi.d.ts\",\n \"import\": \"./dist/openapi.mjs\",\n \"require\": \"./dist/openapi.cjs\"\n },\n \"./openapi-react-query\": {\n \"types\": \"./dist/openapi-react-query.d.ts\",\n \"import\": \"./dist/openapi-react-query.mjs\",\n \"require\": \"./dist/openapi-react-query.cjs\"\n }\n },\n \"bin\": {\n \"gkm\": \"./dist/index.cjs\"\n },\n \"scripts\": {\n \"ts\": \"tsc --noEmit --skipLibCheck src/**/*.ts\",\n \"test\": \"vitest\",\n \"test:once\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/geekmidas/toolbox\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^10.1.0\",\n \"chokidar\": \"~4.0.3\",\n \"commander\": \"^12.1.0\",\n \"dotenv\": \"~17.2.3\",\n \"fast-glob\": \"^3.3.2\",\n \"lodash.kebabcase\": \"^4.1.1\",\n \"openapi-typescript\": \"^7.4.2\",\n \"prompts\": \"~2.4.2\"\n },\n \"devDependencies\": {\n \"@geekmidas/testkit\": \"workspace:*\",\n \"@types/lodash.kebabcase\": \"^4.1.9\",\n \"@types/node\": \"~24.9.1\",\n \"@types/prompts\": \"~2.4.9\",\n \"typescript\": \"^5.8.2\",\n \"vitest\": \"^3.2.4\",\n \"zod\": \"~4.1.13\"\n },\n \"peerDependencies\": {\n \"@geekmidas/constructs\": \"workspace:~\",\n \"@geekmidas/envkit\": \"workspace:~\",\n \"@geekmidas/logger\": \"workspace:~\",\n \"@geekmidas/schema\": \"workspace:~\",\n \"@geekmidas/telescope\": \"workspace:~\"\n },\n \"peerDependenciesMeta\": {\n \"@geekmidas/telescope\": {\n \"optional\": true\n }\n }\n}\n","#!/usr/bin/env -S npx tsx\n\nimport { Command } from 'commander';\nimport pkg from '../package.json' assert { type: 'json' };\nimport { buildCommand } from './build/index.ts';\nimport { devCommand } from './dev/index.ts';\nimport { type InitOptions, initCommand } from './init/index.ts';\nimport { generateReactQueryCommand } from './openapi-react-query.ts';\nimport { openapiCommand } from './openapi.ts';\nimport type { LegacyProvider, MainProvider } from './types.ts';\n\nconst program = new Command();\n\nprogram\n .name('gkm')\n .description('GeekMidas backend framework CLI')\n .version(pkg.version)\n .option('--cwd <path>', 'Change working directory');\n\nprogram\n .command('init')\n .description('Scaffold a new project')\n .argument('[name]', 'Project name')\n .option(\n '--template <template>',\n 'Project template (minimal, api, serverless, worker)',\n )\n .option('--skip-install', 'Skip dependency installation', false)\n .option('-y, --yes', 'Skip prompts, use defaults', false)\n .option('--monorepo', 'Setup as monorepo with packages/models', false)\n .option('--api-path <path>', 'API app path in monorepo (default: apps/api)')\n .action(async (name: string | undefined, options: InitOptions) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await initCommand(name, options);\n } catch (error) {\n console.error('Init failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('build')\n .description('Build handlers from endpoints, functions, and crons')\n .option(\n '--provider <provider>',\n 'Target provider for generated handlers (aws, server)',\n )\n .option(\n '--providers <providers>',\n '[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)',\n )\n .option(\n '--enable-openapi',\n 'Enable OpenAPI documentation generation for server builds',\n )\n .action(\n async (options: {\n provider?: string;\n providers?: string;\n enableOpenapi?: boolean;\n }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n\n // Handle new single provider option\n if (options.provider) {\n if (!['aws', 'server'].includes(options.provider)) {\n console.error(\n `Invalid provider: ${options.provider}. Must be 'aws' or 'server'.`,\n );\n process.exit(1);\n }\n await buildCommand({\n provider: options.provider as MainProvider,\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n // Handle legacy providers option\n else if (options.providers) {\n console.warn(\n '⚠️ --providers flag is deprecated. Use --provider instead.',\n );\n const providerList = [\n ...new Set(options.providers.split(',').map((p) => p.trim())),\n ] as LegacyProvider[];\n await buildCommand({\n providers: providerList,\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n // Default to config-driven build\n else {\n await buildCommand({\n enableOpenApi: options.enableOpenapi || false,\n });\n }\n } catch (error) {\n console.error('Build failed:', (error as Error).message);\n process.exit(1);\n }\n },\n );\n\nprogram\n .command('dev')\n .description('Start development server with automatic reload')\n .option('--port <port>', 'Port to run the development server on', '3000')\n .option(\n '--enable-openapi',\n 'Enable OpenAPI documentation for development server',\n true,\n )\n .action(async (options: { port?: string; enableOpenapi?: boolean }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n\n await devCommand({\n port: options.port ? Number.parseInt(options.port) : 3000,\n enableOpenApi: options.enableOpenapi ?? true,\n });\n } catch (error) {\n console.error('Dev server failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('cron')\n .description('Manage cron jobs')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('Cron management - coming soon\\n');\n });\n\nprogram\n .command('function')\n .description('Manage serverless functions')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('Serverless function management - coming soon\\n');\n });\n\nprogram\n .command('api')\n .description('Manage REST API endpoints')\n .action(() => {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n process.stdout.write('REST API management - coming soon\\n');\n });\n\nprogram\n .command('openapi')\n .description(\n 'Generate OpenAPI specification from endpoints (TypeScript by default)',\n )\n .option(\n '--output <path>',\n 'Output file path for the OpenAPI spec',\n 'openapi.ts',\n )\n .option('--json', 'Generate JSON instead of TypeScript (legacy)', false)\n .action(async (options: { output?: string; json?: boolean }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await openapiCommand(options);\n } catch (error) {\n console.error('OpenAPI generation failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\nprogram\n .command('generate:react-query')\n .description('Generate React Query hooks from OpenAPI specification')\n .option('--input <path>', 'Input OpenAPI spec file path', 'openapi.json')\n .option(\n '--output <path>',\n 'Output file path for generated hooks',\n 'src/api/hooks.ts',\n )\n .option('--name <name>', 'API name prefix for generated code', 'API')\n .action(\n async (options: { input?: string; output?: string; name?: string }) => {\n try {\n const globalOptions = program.opts();\n if (globalOptions.cwd) {\n process.chdir(globalOptions.cwd);\n }\n await generateReactQueryCommand(options);\n } catch (error) {\n console.error(\n 'React Query generation failed:',\n (error as Error).message,\n );\n process.exit(1);\n }\n },\n );\n\nprogram.parse();\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { loadConfig } from "./config-Bq72aj8e.mjs";
2
2
  import { EndpointGenerator } from "./EndpointGenerator-DGivkPLT.mjs";
3
- import { OpenApiTsGenerator } from "./OpenApiTsGenerator-0ZDYWro5.mjs";
3
+ import { OpenApiTsGenerator } from "./OpenApiTsGenerator-BVS4pOH7.mjs";
4
4
  import { mkdir, writeFile } from "node:fs/promises";
5
5
  import { dirname, join } from "node:path";
6
6
 
@@ -71,4 +71,4 @@ async function openapiCommand(options = {}) {
71
71
 
72
72
  //#endregion
73
73
  export { OPENAPI_OUTPUT_PATH, generateOpenApi, openapiCommand, resolveOpenApiConfig };
74
- //# sourceMappingURL=openapi-Dn9MeKg3.mjs.map
74
+ //# sourceMappingURL=openapi-DA9RkPJl.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-Dn9MeKg3.mjs","names":["config: GkmConfig","options: { silent?: boolean }","options: OpenAPIOptions"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { loadConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig } from './types.js';\n\ninterface OpenAPIOptions {\n cwd?: string;\n}\n\n/**\n * Fixed output path for generated OpenAPI client (not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(\n config: GkmConfig,\n): OpenApiConfig & { enabled: boolean } {\n if (config.openapi === false) {\n return { enabled: false };\n }\n\n if (config.openapi === true || config.openapi === undefined) {\n return {\n enabled: config.openapi === true,\n title: 'API Documentation',\n version: '1.0.0',\n description: 'Auto-generated API documentation from endpoints',\n };\n }\n\n return {\n enabled: config.openapi.enabled !== false,\n title: config.openapi.title || 'API Documentation',\n version: config.openapi.version || '1.0.0',\n description:\n config.openapi.description ||\n 'Auto-generated API documentation from endpoints',\n };\n}\n\n/**\n * Generate OpenAPI spec from endpoints\n * @returns Object with output path and endpoint count, or null if disabled\n */\nexport async function generateOpenApi(\n config: GkmConfig,\n options: { silent?: boolean } = {},\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n const logger = options.silent ? { log: () => {} } : console;\n const openApiConfig = resolveOpenApiConfig(config);\n\n if (!openApiConfig.enabled) {\n return null;\n }\n\n const endpointGenerator = new EndpointGenerator();\n const loadedEndpoints = await endpointGenerator.load(config.routes);\n\n if (loadedEndpoints.length === 0) {\n logger.log('No valid endpoints found for OpenAPI generation');\n return null;\n }\n\n const endpoints = loadedEndpoints.map(({ construct }) => construct);\n const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);\n\n await mkdir(dirname(outputPath), { recursive: true });\n\n const tsGenerator = new OpenApiTsGenerator();\n const tsContent = await tsGenerator.generate(endpoints, {\n title: openApiConfig.title!,\n version: openApiConfig.version!,\n description: openApiConfig.description!,\n });\n\n await writeFile(outputPath, tsContent);\n logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);\n\n return { outputPath, endpointCount: loadedEndpoints.length };\n}\n\nexport async function openapiCommand(\n options: OpenAPIOptions = {},\n): Promise<void> {\n const logger = console;\n\n try {\n const config = await loadConfig(options.cwd);\n\n // Enable openapi if not configured\n if (!config.openapi) {\n config.openapi = { enabled: true };\n }\n\n const result = await generateOpenApi(config);\n\n if (result) {\n logger.log(`Found ${result.endpointCount} endpoints`);\n }\n } catch (error) {\n throw new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n }\n}\n"],"mappings":";;;;;;;;;;AAgBA,MAAa,sBAAsB;;;;AAKnC,SAAgB,qBACdA,QACsC;AACtC,KAAI,OAAO,YAAY,MACrB,QAAO,EAAE,SAAS,MAAO;AAG3B,KAAI,OAAO,YAAY,QAAQ,OAAO,mBACpC,QAAO;EACL,SAAS,OAAO,YAAY;EAC5B,OAAO;EACP,SAAS;EACT,aAAa;CACd;AAGH,QAAO;EACL,SAAS,OAAO,QAAQ,YAAY;EACpC,OAAO,OAAO,QAAQ,SAAS;EAC/B,SAAS,OAAO,QAAQ,WAAW;EACnC,aACE,OAAO,QAAQ,eACf;CACH;AACF;;;;;AAMD,eAAsB,gBACpBA,QACAC,UAAgC,CAAE,GAC6B;CAC/D,MAAM,SAAS,QAAQ,SAAS,EAAE,KAAK,MAAM,CAAE,EAAE,IAAG;CACpD,MAAM,gBAAgB,qBAAqB,OAAO;AAElD,MAAK,cAAc,QACjB,QAAO;CAGT,MAAM,oBAAoB,IAAI;CAC9B,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,OAAO,OAAO;AAEnE,KAAI,gBAAgB,WAAW,GAAG;AAChC,SAAO,IAAI,kDAAkD;AAC7D,SAAO;CACR;CAED,MAAM,YAAY,gBAAgB,IAAI,CAAC,EAAE,WAAW,KAAK,UAAU;CACnE,MAAM,aAAa,KAAK,QAAQ,KAAK,EAAE,oBAAoB;AAE3D,OAAM,MAAM,QAAQ,WAAW,EAAE,EAAE,WAAW,KAAM,EAAC;CAErD,MAAM,cAAc,IAAI;CACxB,MAAM,YAAY,MAAM,YAAY,SAAS,WAAW;EACtD,OAAO,cAAc;EACrB,SAAS,cAAc;EACvB,aAAa,cAAc;CAC5B,EAAC;AAEF,OAAM,UAAU,YAAY,UAAU;AACtC,QAAO,KAAK,+BAA+B,oBAAoB,EAAE;AAEjE,QAAO;EAAE;EAAY,eAAe,gBAAgB;CAAQ;AAC7D;AAED,eAAsB,eACpBC,UAA0B,CAAE,GACb;CACf,MAAM,SAAS;AAEf,KAAI;EACF,MAAM,SAAS,MAAM,WAAW,QAAQ,IAAI;AAG5C,OAAK,OAAO,QACV,QAAO,UAAU,EAAE,SAAS,KAAM;EAGpC,MAAM,SAAS,MAAM,gBAAgB,OAAO;AAE5C,MAAI,OACF,QAAO,KAAK,QAAQ,OAAO,cAAc,YAAY;CAExD,SAAQ,OAAO;AACd,QAAM,IAAI,OAAO,6BAA8B,MAAgB,QAAQ;CACxE;AACF"}
1
+ {"version":3,"file":"openapi-DA9RkPJl.mjs","names":["config: GkmConfig","options: { silent?: boolean }","options: OpenAPIOptions"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { loadConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig } from './types.js';\n\ninterface OpenAPIOptions {\n cwd?: string;\n}\n\n/**\n * Fixed output path for generated OpenAPI client (not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(\n config: GkmConfig,\n): OpenApiConfig & { enabled: boolean } {\n if (config.openapi === false) {\n return { enabled: false };\n }\n\n if (config.openapi === true || config.openapi === undefined) {\n return {\n enabled: config.openapi === true,\n title: 'API Documentation',\n version: '1.0.0',\n description: 'Auto-generated API documentation from endpoints',\n };\n }\n\n return {\n enabled: config.openapi.enabled !== false,\n title: config.openapi.title || 'API Documentation',\n version: config.openapi.version || '1.0.0',\n description:\n config.openapi.description ||\n 'Auto-generated API documentation from endpoints',\n };\n}\n\n/**\n * Generate OpenAPI spec from endpoints\n * @returns Object with output path and endpoint count, or null if disabled\n */\nexport async function generateOpenApi(\n config: GkmConfig,\n options: { silent?: boolean } = {},\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n const logger = options.silent ? { log: () => {} } : console;\n const openApiConfig = resolveOpenApiConfig(config);\n\n if (!openApiConfig.enabled) {\n return null;\n }\n\n const endpointGenerator = new EndpointGenerator();\n const loadedEndpoints = await endpointGenerator.load(config.routes);\n\n if (loadedEndpoints.length === 0) {\n logger.log('No valid endpoints found for OpenAPI generation');\n return null;\n }\n\n const endpoints = loadedEndpoints.map(({ construct }) => construct);\n const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);\n\n await mkdir(dirname(outputPath), { recursive: true });\n\n const tsGenerator = new OpenApiTsGenerator();\n const tsContent = await tsGenerator.generate(endpoints, {\n title: openApiConfig.title!,\n version: openApiConfig.version!,\n description: openApiConfig.description!,\n });\n\n await writeFile(outputPath, tsContent);\n logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);\n\n return { outputPath, endpointCount: loadedEndpoints.length };\n}\n\nexport async function openapiCommand(\n options: OpenAPIOptions = {},\n): Promise<void> {\n const logger = console;\n\n try {\n const config = await loadConfig(options.cwd);\n\n // Enable openapi if not configured\n if (!config.openapi) {\n config.openapi = { enabled: true };\n }\n\n const result = await generateOpenApi(config);\n\n if (result) {\n logger.log(`Found ${result.endpointCount} endpoints`);\n }\n } catch (error) {\n throw new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n }\n}\n"],"mappings":";;;;;;;;;;AAgBA,MAAa,sBAAsB;;;;AAKnC,SAAgB,qBACdA,QACsC;AACtC,KAAI,OAAO,YAAY,MACrB,QAAO,EAAE,SAAS,MAAO;AAG3B,KAAI,OAAO,YAAY,QAAQ,OAAO,mBACpC,QAAO;EACL,SAAS,OAAO,YAAY;EAC5B,OAAO;EACP,SAAS;EACT,aAAa;CACd;AAGH,QAAO;EACL,SAAS,OAAO,QAAQ,YAAY;EACpC,OAAO,OAAO,QAAQ,SAAS;EAC/B,SAAS,OAAO,QAAQ,WAAW;EACnC,aACE,OAAO,QAAQ,eACf;CACH;AACF;;;;;AAMD,eAAsB,gBACpBA,QACAC,UAAgC,CAAE,GAC6B;CAC/D,MAAM,SAAS,QAAQ,SAAS,EAAE,KAAK,MAAM,CAAE,EAAE,IAAG;CACpD,MAAM,gBAAgB,qBAAqB,OAAO;AAElD,MAAK,cAAc,QACjB,QAAO;CAGT,MAAM,oBAAoB,IAAI;CAC9B,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,OAAO,OAAO;AAEnE,KAAI,gBAAgB,WAAW,GAAG;AAChC,SAAO,IAAI,kDAAkD;AAC7D,SAAO;CACR;CAED,MAAM,YAAY,gBAAgB,IAAI,CAAC,EAAE,WAAW,KAAK,UAAU;CACnE,MAAM,aAAa,KAAK,QAAQ,KAAK,EAAE,oBAAoB;AAE3D,OAAM,MAAM,QAAQ,WAAW,EAAE,EAAE,WAAW,KAAM,EAAC;CAErD,MAAM,cAAc,IAAI;CACxB,MAAM,YAAY,MAAM,YAAY,SAAS,WAAW;EACtD,OAAO,cAAc;EACrB,SAAS,cAAc;EACvB,aAAa,cAAc;CAC5B,EAAC;AAEF,OAAM,UAAU,YAAY,UAAU;AACtC,QAAO,KAAK,+BAA+B,oBAAoB,EAAE;AAEjE,QAAO;EAAE;EAAY,eAAe,gBAAgB;CAAQ;AAC7D;AAED,eAAsB,eACpBC,UAA0B,CAAE,GACb;CACf,MAAM,SAAS;AAEf,KAAI;EACF,MAAM,SAAS,MAAM,WAAW,QAAQ,IAAI;AAG5C,OAAK,OAAO,QACV,QAAO,UAAU,EAAE,SAAS,KAAM;EAGpC,MAAM,SAAS,MAAM,gBAAgB,OAAO;AAE5C,MAAI,OACF,QAAO,KAAK,QAAQ,OAAO,cAAc,YAAY;CAExD,SAAQ,OAAO;AACd,QAAM,IAAI,OAAO,6BAA8B,MAAgB,QAAQ;CACxE;AACF"}
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require('./chunk-CUT6urMc.cjs');
2
2
  const require_config = require('./config-CFls09Ey.cjs');
3
3
  const require_EndpointGenerator = require('./EndpointGenerator-npWEDoK2.cjs');
4
- const require_OpenApiTsGenerator = require('./OpenApiTsGenerator-wLwpaq_I.cjs');
4
+ const require_OpenApiTsGenerator = require('./OpenApiTsGenerator-gPIIyppX.cjs');
5
5
  const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
6
6
  const node_path = require_chunk.__toESM(require("node:path"));
7
7
 
@@ -95,4 +95,4 @@ Object.defineProperty(exports, 'resolveOpenApiConfig', {
95
95
  return resolveOpenApiConfig;
96
96
  }
97
97
  });
98
- //# sourceMappingURL=openapi-CTae4ybf.cjs.map
98
+ //# sourceMappingURL=openapi-DZH6RQHk.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-CTae4ybf.cjs","names":["config: GkmConfig","options: { silent?: boolean }","EndpointGenerator","OpenApiTsGenerator","options: OpenAPIOptions"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { loadConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig } from './types.js';\n\ninterface OpenAPIOptions {\n cwd?: string;\n}\n\n/**\n * Fixed output path for generated OpenAPI client (not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(\n config: GkmConfig,\n): OpenApiConfig & { enabled: boolean } {\n if (config.openapi === false) {\n return { enabled: false };\n }\n\n if (config.openapi === true || config.openapi === undefined) {\n return {\n enabled: config.openapi === true,\n title: 'API Documentation',\n version: '1.0.0',\n description: 'Auto-generated API documentation from endpoints',\n };\n }\n\n return {\n enabled: config.openapi.enabled !== false,\n title: config.openapi.title || 'API Documentation',\n version: config.openapi.version || '1.0.0',\n description:\n config.openapi.description ||\n 'Auto-generated API documentation from endpoints',\n };\n}\n\n/**\n * Generate OpenAPI spec from endpoints\n * @returns Object with output path and endpoint count, or null if disabled\n */\nexport async function generateOpenApi(\n config: GkmConfig,\n options: { silent?: boolean } = {},\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n const logger = options.silent ? { log: () => {} } : console;\n const openApiConfig = resolveOpenApiConfig(config);\n\n if (!openApiConfig.enabled) {\n return null;\n }\n\n const endpointGenerator = new EndpointGenerator();\n const loadedEndpoints = await endpointGenerator.load(config.routes);\n\n if (loadedEndpoints.length === 0) {\n logger.log('No valid endpoints found for OpenAPI generation');\n return null;\n }\n\n const endpoints = loadedEndpoints.map(({ construct }) => construct);\n const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);\n\n await mkdir(dirname(outputPath), { recursive: true });\n\n const tsGenerator = new OpenApiTsGenerator();\n const tsContent = await tsGenerator.generate(endpoints, {\n title: openApiConfig.title!,\n version: openApiConfig.version!,\n description: openApiConfig.description!,\n });\n\n await writeFile(outputPath, tsContent);\n logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);\n\n return { outputPath, endpointCount: loadedEndpoints.length };\n}\n\nexport async function openapiCommand(\n options: OpenAPIOptions = {},\n): Promise<void> {\n const logger = console;\n\n try {\n const config = await loadConfig(options.cwd);\n\n // Enable openapi if not configured\n if (!config.openapi) {\n config.openapi = { enabled: true };\n }\n\n const result = await generateOpenApi(config);\n\n if (result) {\n logger.log(`Found ${result.endpointCount} endpoints`);\n }\n } catch (error) {\n throw new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n }\n}\n"],"mappings":";;;;;;;;;;;AAgBA,MAAa,sBAAsB;;;;AAKnC,SAAgB,qBACdA,QACsC;AACtC,KAAI,OAAO,YAAY,MACrB,QAAO,EAAE,SAAS,MAAO;AAG3B,KAAI,OAAO,YAAY,QAAQ,OAAO,mBACpC,QAAO;EACL,SAAS,OAAO,YAAY;EAC5B,OAAO;EACP,SAAS;EACT,aAAa;CACd;AAGH,QAAO;EACL,SAAS,OAAO,QAAQ,YAAY;EACpC,OAAO,OAAO,QAAQ,SAAS;EAC/B,SAAS,OAAO,QAAQ,WAAW;EACnC,aACE,OAAO,QAAQ,eACf;CACH;AACF;;;;;AAMD,eAAsB,gBACpBA,QACAC,UAAgC,CAAE,GAC6B;CAC/D,MAAM,SAAS,QAAQ,SAAS,EAAE,KAAK,MAAM,CAAE,EAAE,IAAG;CACpD,MAAM,gBAAgB,qBAAqB,OAAO;AAElD,MAAK,cAAc,QACjB,QAAO;CAGT,MAAM,oBAAoB,IAAIC;CAC9B,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,OAAO,OAAO;AAEnE,KAAI,gBAAgB,WAAW,GAAG;AAChC,SAAO,IAAI,kDAAkD;AAC7D,SAAO;CACR;CAED,MAAM,YAAY,gBAAgB,IAAI,CAAC,EAAE,WAAW,KAAK,UAAU;CACnE,MAAM,aAAa,oBAAK,QAAQ,KAAK,EAAE,oBAAoB;AAE3D,OAAM,4BAAM,uBAAQ,WAAW,EAAE,EAAE,WAAW,KAAM,EAAC;CAErD,MAAM,cAAc,IAAIC;CACxB,MAAM,YAAY,MAAM,YAAY,SAAS,WAAW;EACtD,OAAO,cAAc;EACrB,SAAS,cAAc;EACvB,aAAa,cAAc;CAC5B,EAAC;AAEF,OAAM,gCAAU,YAAY,UAAU;AACtC,QAAO,KAAK,+BAA+B,oBAAoB,EAAE;AAEjE,QAAO;EAAE;EAAY,eAAe,gBAAgB;CAAQ;AAC7D;AAED,eAAsB,eACpBC,UAA0B,CAAE,GACb;CACf,MAAM,SAAS;AAEf,KAAI;EACF,MAAM,SAAS,MAAM,0BAAW,QAAQ,IAAI;AAG5C,OAAK,OAAO,QACV,QAAO,UAAU,EAAE,SAAS,KAAM;EAGpC,MAAM,SAAS,MAAM,gBAAgB,OAAO;AAE5C,MAAI,OACF,QAAO,KAAK,QAAQ,OAAO,cAAc,YAAY;CAExD,SAAQ,OAAO;AACd,QAAM,IAAI,OAAO,6BAA8B,MAAgB,QAAQ;CACxE;AACF"}
1
+ {"version":3,"file":"openapi-DZH6RQHk.cjs","names":["config: GkmConfig","options: { silent?: boolean }","EndpointGenerator","OpenApiTsGenerator","options: OpenAPIOptions"],"sources":["../src/openapi.ts"],"sourcesContent":["#!/usr/bin/env -S npx tsx\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { loadConfig } from './config.js';\nimport { EndpointGenerator } from './generators/EndpointGenerator.js';\nimport { OpenApiTsGenerator } from './generators/OpenApiTsGenerator.js';\nimport type { GkmConfig, OpenApiConfig } from './types.js';\n\ninterface OpenAPIOptions {\n cwd?: string;\n}\n\n/**\n * Fixed output path for generated OpenAPI client (not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Resolve OpenAPI config from GkmConfig\n */\nexport function resolveOpenApiConfig(\n config: GkmConfig,\n): OpenApiConfig & { enabled: boolean } {\n if (config.openapi === false) {\n return { enabled: false };\n }\n\n if (config.openapi === true || config.openapi === undefined) {\n return {\n enabled: config.openapi === true,\n title: 'API Documentation',\n version: '1.0.0',\n description: 'Auto-generated API documentation from endpoints',\n };\n }\n\n return {\n enabled: config.openapi.enabled !== false,\n title: config.openapi.title || 'API Documentation',\n version: config.openapi.version || '1.0.0',\n description:\n config.openapi.description ||\n 'Auto-generated API documentation from endpoints',\n };\n}\n\n/**\n * Generate OpenAPI spec from endpoints\n * @returns Object with output path and endpoint count, or null if disabled\n */\nexport async function generateOpenApi(\n config: GkmConfig,\n options: { silent?: boolean } = {},\n): Promise<{ outputPath: string; endpointCount: number } | null> {\n const logger = options.silent ? { log: () => {} } : console;\n const openApiConfig = resolveOpenApiConfig(config);\n\n if (!openApiConfig.enabled) {\n return null;\n }\n\n const endpointGenerator = new EndpointGenerator();\n const loadedEndpoints = await endpointGenerator.load(config.routes);\n\n if (loadedEndpoints.length === 0) {\n logger.log('No valid endpoints found for OpenAPI generation');\n return null;\n }\n\n const endpoints = loadedEndpoints.map(({ construct }) => construct);\n const outputPath = join(process.cwd(), OPENAPI_OUTPUT_PATH);\n\n await mkdir(dirname(outputPath), { recursive: true });\n\n const tsGenerator = new OpenApiTsGenerator();\n const tsContent = await tsGenerator.generate(endpoints, {\n title: openApiConfig.title!,\n version: openApiConfig.version!,\n description: openApiConfig.description!,\n });\n\n await writeFile(outputPath, tsContent);\n logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);\n\n return { outputPath, endpointCount: loadedEndpoints.length };\n}\n\nexport async function openapiCommand(\n options: OpenAPIOptions = {},\n): Promise<void> {\n const logger = console;\n\n try {\n const config = await loadConfig(options.cwd);\n\n // Enable openapi if not configured\n if (!config.openapi) {\n config.openapi = { enabled: true };\n }\n\n const result = await generateOpenApi(config);\n\n if (result) {\n logger.log(`Found ${result.endpointCount} endpoints`);\n }\n } catch (error) {\n throw new Error(`OpenAPI generation failed: ${(error as Error).message}`);\n }\n}\n"],"mappings":";;;;;;;;;;;AAgBA,MAAa,sBAAsB;;;;AAKnC,SAAgB,qBACdA,QACsC;AACtC,KAAI,OAAO,YAAY,MACrB,QAAO,EAAE,SAAS,MAAO;AAG3B,KAAI,OAAO,YAAY,QAAQ,OAAO,mBACpC,QAAO;EACL,SAAS,OAAO,YAAY;EAC5B,OAAO;EACP,SAAS;EACT,aAAa;CACd;AAGH,QAAO;EACL,SAAS,OAAO,QAAQ,YAAY;EACpC,OAAO,OAAO,QAAQ,SAAS;EAC/B,SAAS,OAAO,QAAQ,WAAW;EACnC,aACE,OAAO,QAAQ,eACf;CACH;AACF;;;;;AAMD,eAAsB,gBACpBA,QACAC,UAAgC,CAAE,GAC6B;CAC/D,MAAM,SAAS,QAAQ,SAAS,EAAE,KAAK,MAAM,CAAE,EAAE,IAAG;CACpD,MAAM,gBAAgB,qBAAqB,OAAO;AAElD,MAAK,cAAc,QACjB,QAAO;CAGT,MAAM,oBAAoB,IAAIC;CAC9B,MAAM,kBAAkB,MAAM,kBAAkB,KAAK,OAAO,OAAO;AAEnE,KAAI,gBAAgB,WAAW,GAAG;AAChC,SAAO,IAAI,kDAAkD;AAC7D,SAAO;CACR;CAED,MAAM,YAAY,gBAAgB,IAAI,CAAC,EAAE,WAAW,KAAK,UAAU;CACnE,MAAM,aAAa,oBAAK,QAAQ,KAAK,EAAE,oBAAoB;AAE3D,OAAM,4BAAM,uBAAQ,WAAW,EAAE,EAAE,WAAW,KAAM,EAAC;CAErD,MAAM,cAAc,IAAIC;CACxB,MAAM,YAAY,MAAM,YAAY,SAAS,WAAW;EACtD,OAAO,cAAc;EACrB,SAAS,cAAc;EACvB,aAAa,cAAc;CAC5B,EAAC;AAEF,OAAM,gCAAU,YAAY,UAAU;AACtC,QAAO,KAAK,+BAA+B,oBAAoB,EAAE;AAEjE,QAAO;EAAE;EAAY,eAAe,gBAAgB;CAAQ;AAC7D;AAED,eAAsB,eACpBC,UAA0B,CAAE,GACb;CACf,MAAM,SAAS;AAEf,KAAI;EACF,MAAM,SAAS,MAAM,0BAAW,QAAQ,IAAI;AAG5C,OAAK,OAAO,QACV,QAAO,UAAU,EAAE,SAAS,KAAM;EAGpC,MAAM,SAAS,MAAM,gBAAgB,OAAO;AAE5C,MAAI,OACF,QAAO,KAAK,QAAQ,OAAO,cAAc,YAAY;CAExD,SAAQ,OAAO;AACd,QAAM,IAAI,OAAO,6BAA8B,MAAgB,QAAQ;CACxE;AACF"}
package/dist/openapi.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
  require('./config-CFls09Ey.cjs');
3
3
  require('./Generator-CLVplqm2.cjs');
4
4
  require('./EndpointGenerator-npWEDoK2.cjs');
5
- require('./OpenApiTsGenerator-wLwpaq_I.cjs');
6
- const require_openapi = require('./openapi-CTae4ybf.cjs');
5
+ require('./OpenApiTsGenerator-gPIIyppX.cjs');
6
+ const require_openapi = require('./openapi-DZH6RQHk.cjs');
7
7
 
8
8
  exports.OPENAPI_OUTPUT_PATH = require_openapi.OPENAPI_OUTPUT_PATH;
9
9
  exports.generateOpenApi = require_openapi.generateOpenApi;
package/dist/openapi.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import "./config-Bq72aj8e.mjs";
3
3
  import "./Generator-CDt4pB3W.mjs";
4
4
  import "./EndpointGenerator-DGivkPLT.mjs";
5
- import "./OpenApiTsGenerator-0ZDYWro5.mjs";
6
- import { OPENAPI_OUTPUT_PATH, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-Dn9MeKg3.mjs";
5
+ import "./OpenApiTsGenerator-BVS4pOH7.mjs";
6
+ import { OPENAPI_OUTPUT_PATH, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-DA9RkPJl.mjs";
7
7
 
8
8
  export { OPENAPI_OUTPUT_PATH, generateOpenApi, openapiCommand, resolveOpenApiConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs",
5
5
  "private": false,
6
6
  "type": "module",
@@ -50,13 +50,13 @@
50
50
  "typescript": "^5.8.2",
51
51
  "vitest": "^3.2.4",
52
52
  "zod": "~4.1.13",
53
- "@geekmidas/testkit": "0.0.17"
53
+ "@geekmidas/testkit": "0.1.0"
54
54
  },
55
55
  "peerDependencies": {
56
- "@geekmidas/constructs": "~0.2.2",
57
- "@geekmidas/envkit": "~0.1.0",
58
- "@geekmidas/logger": "~0.0.1",
56
+ "@geekmidas/constructs": "~0.2.4",
59
57
  "@geekmidas/schema": "~0.0.3",
58
+ "@geekmidas/logger": "~0.1.0",
59
+ "@geekmidas/envkit": "~0.1.0",
60
60
  "@geekmidas/telescope": "~0.0.1"
61
61
  },
62
62
  "peerDependenciesMeta": {
package/src/config.ts CHANGED
@@ -2,6 +2,7 @@ import { existsSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import type { GkmConfig } from './types.ts';
4
4
 
5
+ export type { GkmConfig } from './types.ts';
5
6
  /**
6
7
  * Define GKM configuration with full TypeScript support.
7
8
  * This is an identity function that provides type safety and autocomplete.
@@ -7,6 +7,9 @@ import {
7
7
  normalizeTelescopeConfig,
8
8
  } from '../index';
9
9
 
10
+ // Skip port-related tests in CI due to flaky port binding issues
11
+ const describePortTests = process.env.CI ? describe.skip : describe;
12
+
10
13
  // Track servers to clean up after each test
11
14
  const activeServers: ReturnType<typeof createServer>[] = [];
12
15
 
@@ -49,7 +52,7 @@ function occupyPort(
49
52
  });
50
53
  }
51
54
 
52
- describe('Port Availability Functions', () => {
55
+ describePortTests('Port Availability Functions', () => {
53
56
  describe('isPortAvailable', () => {
54
57
  it('should return true for an available port', async () => {
55
58
  // Get a random port, close it, then check availability
@@ -149,7 +152,7 @@ describe('Port Availability Functions', () => {
149
152
  });
150
153
  });
151
154
 
152
- describe('DevServer', () => {
155
+ describePortTests('DevServer', () => {
153
156
  describe('port selection', () => {
154
157
  it('should use requested port when available', async () => {
155
158
  // Get a random port, close it, then use as requested
@@ -172,7 +175,7 @@ describe('DevServer', () => {
172
175
  });
173
176
  });
174
177
 
175
- describe('devCommand edge cases', () => {
178
+ describePortTests('devCommand edge cases', () => {
176
179
  it('should handle port conflicts gracefully', async () => {
177
180
  const { port } = await occupyPort(0);
178
181
 
@@ -757,7 +757,7 @@ export const apiInfo = {
757
757
  * Available security schemes for this API.
758
758
  * Maps authorizer names to OpenAPI security scheme definitions.
759
759
  */
760
- export const securitySchemes = ${JSON.stringify(securitySchemesObj, null, 2).replace(/"([^"]+)":/g, '$1:')} as const satisfies Record<string, SecuritySchemeObject>;
760
+ export const securitySchemes = ${JSON.stringify(securitySchemesObj, null, 2).replace(/"([a-zA-Z_$][a-zA-Z0-9_$]*)":/g, '$1:')} as const satisfies Record<string, SecuritySchemeObject>;
761
761
 
762
762
  export type SecuritySchemeId = ${schemeNames || 'never'};
763
763