@geekmidas/cli 0.8.0 → 0.10.0
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.
- package/dist/{config-Bq72aj8e.mjs → config-BrkUalUh.mjs} +4 -2
- package/dist/config-BrkUalUh.mjs.map +1 -0
- package/dist/{config-CFls09Ey.cjs → config-C9aXOHBe.cjs} +4 -2
- package/dist/config-C9aXOHBe.cjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +1 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +1 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +1 -1
- package/dist/index.cjs +27 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +27 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-CHhTPief.cjs → openapi-BeHLKcwP.cjs} +13 -13
- package/dist/{openapi-CHhTPief.cjs.map → openapi-BeHLKcwP.cjs.map} +1 -1
- package/dist/{openapi--vOy9mo4.mjs → openapi-CZLI4QTr.mjs} +13 -13
- package/dist/{openapi--vOy9mo4.mjs.map → openapi-CZLI4QTr.mjs.map} +1 -1
- package/dist/openapi-react-query.d.cts.map +1 -0
- package/dist/openapi-react-query.d.mts.map +1 -0
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts.map +1 -0
- package/dist/openapi.d.mts.map +1 -0
- package/dist/openapi.mjs +2 -2
- package/dist/types-DXgiA1sF.d.mts.map +1 -0
- package/dist/types-b-vwGpqc.d.cts.map +1 -0
- package/package.json +7 -7
- package/src/__tests__/test-helpers.ts +3 -2
- package/src/config.ts +3 -1
- package/src/dev/index.ts +35 -11
- package/src/generators/OpenApiTsGenerator.ts +11 -11
- package/src/index.ts +11 -18
- package/tsconfig.json +9 -0
- package/dist/config-Bq72aj8e.mjs.map +0 -1
- package/dist/config-CFls09Ey.cjs.map +0 -1
|
@@ -40,7 +40,9 @@ function defineConfig(config) {
|
|
|
40
40
|
* // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }
|
|
41
41
|
*/
|
|
42
42
|
function parseModuleConfig(configString, defaultAlias) {
|
|
43
|
-
const
|
|
43
|
+
const parts = configString.split("#");
|
|
44
|
+
const path = parts[0] ?? configString;
|
|
45
|
+
const exportName = parts[1];
|
|
44
46
|
const importPattern = !exportName ? defaultAlias : exportName === defaultAlias ? `{ ${defaultAlias} }` : `{ ${exportName} as ${defaultAlias} }`;
|
|
45
47
|
return {
|
|
46
48
|
path,
|
|
@@ -72,4 +74,4 @@ async function loadConfig(cwd = process.cwd()) {
|
|
|
72
74
|
|
|
73
75
|
//#endregion
|
|
74
76
|
export { defineConfig, loadConfig, parseModuleConfig };
|
|
75
|
-
//# sourceMappingURL=config-
|
|
77
|
+
//# sourceMappingURL=config-BrkUalUh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-BrkUalUh.mjs","names":["config: GkmConfig","configString: string","defaultAlias: string","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { GkmConfig } from './types.ts';\n\nexport type { GkmConfig } from './types.ts';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n return config;\n}\n\nexport interface ParsedModuleConfig {\n path: string;\n importPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n configString: string,\n defaultAlias: string,\n): ParsedModuleConfig {\n const parts = configString.split('#');\n const path = parts[0] ?? configString;\n const exportName = parts[1];\n const importPattern = !exportName\n ? defaultAlias\n : exportName === defaultAlias\n ? `{ ${defaultAlias} }`\n : `{ ${exportName} as ${defaultAlias} }`;\n\n return { path, importPattern };\n}\n\nexport async function loadConfig(\n cwd: string = process.cwd(),\n): Promise<GkmConfig> {\n const files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n let configPath = '';\n\n for (const file of files) {\n const path = join(cwd, file);\n if (existsSync(path)) {\n configPath = path;\n break;\n }\n }\n\n if (!configPath) {\n throw new Error(\n 'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n );\n }\n\n try {\n const config = await import(configPath);\n return config.default;\n } catch (error) {\n throw new Error(\n `Failed to load gkm.config.json: ${(error as Error).message}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aAAaA,QAA8B;AACzD,QAAO;AACR;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,kBACdC,cACAC,cACoB;CACpB,MAAM,QAAQ,aAAa,MAAM,IAAI;CACrC,MAAM,OAAO,MAAM,MAAM;CACzB,MAAM,aAAa,MAAM;CACzB,MAAM,iBAAiB,aACnB,eACA,eAAe,gBACZ,IAAI,aAAa,OACjB,IAAI,WAAW,MAAM,aAAa;AAEzC,QAAO;EAAE;EAAM;CAAe;AAC/B;AAED,eAAsB,WACpBC,MAAc,QAAQ,KAAK,EACP;CACpB,MAAM,QAAQ;EAAC;EAAmB;EAAiB;CAAgB;CACnE,IAAI,aAAa;AAEjB,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,MAAI,WAAW,KAAK,EAAE;AACpB,gBAAa;AACb;EACD;CACF;AAED,MAAK,WACH,OAAM,IAAI,MACR;AAIJ,KAAI;EACF,MAAM,SAAS,MAAM,OAAO;AAC5B,SAAO,OAAO;CACf,SAAQ,OAAO;AACd,QAAM,IAAI,OACP,kCAAmC,MAAgB,QAAQ;CAE/D;AACF"}
|
|
@@ -41,7 +41,9 @@ function defineConfig(config) {
|
|
|
41
41
|
* // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }
|
|
42
42
|
*/
|
|
43
43
|
function parseModuleConfig(configString, defaultAlias) {
|
|
44
|
-
const
|
|
44
|
+
const parts = configString.split("#");
|
|
45
|
+
const path$1 = parts[0] ?? configString;
|
|
46
|
+
const exportName = parts[1];
|
|
45
47
|
const importPattern = !exportName ? defaultAlias : exportName === defaultAlias ? `{ ${defaultAlias} }` : `{ ${exportName} as ${defaultAlias} }`;
|
|
46
48
|
return {
|
|
47
49
|
path: path$1,
|
|
@@ -90,4 +92,4 @@ Object.defineProperty(exports, 'parseModuleConfig', {
|
|
|
90
92
|
return parseModuleConfig;
|
|
91
93
|
}
|
|
92
94
|
});
|
|
93
|
-
//# sourceMappingURL=config-
|
|
95
|
+
//# sourceMappingURL=config-C9aXOHBe.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-C9aXOHBe.cjs","names":["config: GkmConfig","configString: string","defaultAlias: string","path","cwd: string"],"sources":["../src/config.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport { join } from 'path';\nimport type { GkmConfig } from './types.ts';\n\nexport type { GkmConfig } from './types.ts';\n/**\n * Define GKM configuration with full TypeScript support.\n * This is an identity function that provides type safety and autocomplete.\n *\n * @example\n * ```ts\n * // gkm.config.ts\n * import { defineConfig } from '@geekmidas/cli/config';\n *\n * export default defineConfig({\n * routes: './src/endpoints/**\\/*.ts',\n * envParser: './src/config/env',\n * logger: './src/config/logger',\n * telescope: true,\n * });\n * ```\n */\nexport function defineConfig(config: GkmConfig): GkmConfig {\n return config;\n}\n\nexport interface ParsedModuleConfig {\n path: string;\n importPattern: string;\n}\n\n/**\n * Parse a module config string into path and import pattern.\n *\n * @param configString - Config string in format \"./path/to/module\" or \"./path/to/module#exportName\"\n * @param defaultAlias - The default alias name to use if no export name specified\n * @returns Object with path and import pattern\n *\n * @example\n * parseModuleConfig('./src/config/env', 'envParser')\n * // { path: './src/config/env', importPattern: 'envParser' }\n *\n * parseModuleConfig('./src/config/env#envParser', 'envParser')\n * // { path: './src/config/env', importPattern: '{ envParser }' }\n *\n * parseModuleConfig('./src/config/env#myEnv', 'envParser')\n * // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }\n */\nexport function parseModuleConfig(\n configString: string,\n defaultAlias: string,\n): ParsedModuleConfig {\n const parts = configString.split('#');\n const path = parts[0] ?? configString;\n const exportName = parts[1];\n const importPattern = !exportName\n ? defaultAlias\n : exportName === defaultAlias\n ? `{ ${defaultAlias} }`\n : `{ ${exportName} as ${defaultAlias} }`;\n\n return { path, importPattern };\n}\n\nexport async function loadConfig(\n cwd: string = process.cwd(),\n): Promise<GkmConfig> {\n const files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];\n let configPath = '';\n\n for (const file of files) {\n const path = join(cwd, file);\n if (existsSync(path)) {\n configPath = path;\n break;\n }\n }\n\n if (!configPath) {\n throw new Error(\n 'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',\n );\n }\n\n try {\n const config = await import(configPath);\n return config.default;\n } catch (error) {\n throw new Error(\n `Failed to load gkm.config.json: ${(error as Error).message}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aAAaA,QAA8B;AACzD,QAAO;AACR;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,kBACdC,cACAC,cACoB;CACpB,MAAM,QAAQ,aAAa,MAAM,IAAI;CACrC,MAAMC,SAAO,MAAM,MAAM;CACzB,MAAM,aAAa,MAAM;CACzB,MAAM,iBAAiB,aACnB,eACA,eAAe,gBACZ,IAAI,aAAa,OACjB,IAAI,WAAW,MAAM,aAAa;AAEzC,QAAO;EAAE;EAAM;CAAe;AAC/B;AAED,eAAsB,WACpBC,MAAc,QAAQ,KAAK,EACP;CACpB,MAAM,QAAQ;EAAC;EAAmB;EAAiB;CAAgB;CACnE,IAAI,aAAa;AAEjB,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAMD,SAAO,eAAK,KAAK,KAAK;AAC5B,MAAI,mBAAWA,OAAK,EAAE;AACpB,gBAAaA;AACb;EACD;CACF;AAED,MAAK,WACH,OAAM,IAAI,MACR;AAIJ,KAAI;EACF,MAAM,SAAS,MAAM,OAAO;AAC5B,SAAO,OAAO;CACf,SAAQ,OAAO;AACd,QAAM,IAAI,OACP,kCAAmC,MAAgB,QAAQ;CAE/D;AACF"}
|
package/dist/config.cjs
CHANGED
package/dist/config.d.cts
CHANGED
|
@@ -43,6 +43,7 @@ interface ParsedModuleConfig {
|
|
|
43
43
|
*/
|
|
44
44
|
declare function parseModuleConfig(configString: string, defaultAlias: string): ParsedModuleConfig;
|
|
45
45
|
declare function loadConfig(cwd?: string): Promise<GkmConfig>;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
46
47
|
//#endregion
|
|
47
48
|
export { GkmConfig, ParsedModuleConfig, defineConfig, loadConfig, parseModuleConfig };
|
|
48
49
|
//# sourceMappingURL=config.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;AAsBA;;;;AAA0D;AAI1D;AAsBA;AAgBA;;;;AAEU;;;;;iBA5CM,YAAA,SAAqB,YAAY;UAIhC,kBAAA;;;;;;;;;;;;;;;;;;;;;iBAsBD,iBAAA,8CAGb;iBAamB,UAAA,gBAEnB,QAAQ"}
|
package/dist/config.d.mts
CHANGED
|
@@ -43,6 +43,7 @@ interface ParsedModuleConfig {
|
|
|
43
43
|
*/
|
|
44
44
|
declare function parseModuleConfig(configString: string, defaultAlias: string): ParsedModuleConfig;
|
|
45
45
|
declare function loadConfig(cwd?: string): Promise<GkmConfig>;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
46
47
|
//#endregion
|
|
47
48
|
export { GkmConfig, ParsedModuleConfig, defineConfig, loadConfig, parseModuleConfig };
|
|
48
49
|
//# sourceMappingURL=config.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"sourcesContent":[],"mappings":";;;;;AAsBA;;;;AAA0D;AAI1D;AAsBA;AAgBA;;;;AAEU;;;;;iBA5CM,YAAA,SAAqB,YAAY;UAIhC,kBAAA;;;;;;;;;;;;;;;;;;;;;iBAsBD,iBAAA,8CAGb;iBAamB,UAAA,gBAEnB,QAAQ"}
|
package/dist/config.mjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env -S npx tsx
|
|
2
2
|
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
3
|
-
const require_config = require('./config-
|
|
4
|
-
const require_openapi = require('./openapi-
|
|
3
|
+
const require_config = require('./config-C9aXOHBe.cjs');
|
|
4
|
+
const require_openapi = require('./openapi-BeHLKcwP.cjs');
|
|
5
5
|
const require_openapi_react_query = require('./openapi-react-query-o5iMi8tz.cjs');
|
|
6
6
|
const path = require_chunk.__toESM(require("path"));
|
|
7
7
|
const commander = require_chunk.__toESM(require("commander"));
|
|
@@ -20,7 +20,7 @@ const prompts = require_chunk.__toESM(require("prompts"));
|
|
|
20
20
|
|
|
21
21
|
//#region package.json
|
|
22
22
|
var name = "@geekmidas/cli";
|
|
23
|
-
var version = "0.
|
|
23
|
+
var version = "0.10.0";
|
|
24
24
|
var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
|
|
25
25
|
var private$1 = false;
|
|
26
26
|
var type = "module";
|
|
@@ -621,11 +621,12 @@ async function devCommand(options) {
|
|
|
621
621
|
await buildServer(config, buildContext, resolved.providers[0], enableOpenApi);
|
|
622
622
|
if (enableOpenApi) await require_openapi.generateOpenApi(config);
|
|
623
623
|
const runtime = config.runtime ?? "node";
|
|
624
|
-
const devServer = new DevServer(resolved.providers[0], options.port || 3e3, enableOpenApi, telescope, studio, runtime);
|
|
624
|
+
const devServer = new DevServer(resolved.providers[0], options.port || 3e3, options.portExplicit ?? false, enableOpenApi, telescope, studio, runtime);
|
|
625
625
|
await devServer.start();
|
|
626
|
-
const envParserFile = config.envParser.split("#")[0];
|
|
627
|
-
const loggerFile = config.logger.split("#")[0];
|
|
628
|
-
const
|
|
626
|
+
const envParserFile = config.envParser.split("#")[0] ?? config.envParser;
|
|
627
|
+
const loggerFile = config.logger.split("#")[0] ?? config.logger;
|
|
628
|
+
const hooksFileParts = config.hooks?.server?.split("#");
|
|
629
|
+
const hooksFile = hooksFileParts?.[0];
|
|
629
630
|
const watchPatterns = [
|
|
630
631
|
config.routes,
|
|
631
632
|
...config.functions ? [config.functions] : [],
|
|
@@ -634,7 +635,7 @@ async function devCommand(options) {
|
|
|
634
635
|
envParserFile.endsWith(".ts") ? envParserFile : `${envParserFile}.ts`,
|
|
635
636
|
loggerFile.endsWith(".ts") ? loggerFile : `${loggerFile}.ts`,
|
|
636
637
|
...hooksFile ? [hooksFile.endsWith(".ts") ? hooksFile : `${hooksFile}.ts`] : []
|
|
637
|
-
].flat();
|
|
638
|
+
].flat().filter((p) => typeof p === "string");
|
|
638
639
|
const normalizedPatterns = watchPatterns.map((p) => p.startsWith("./") ? p.slice(2) : p);
|
|
639
640
|
logger$2.log(`👀 Watching for changes in: ${normalizedPatterns.join(", ")}`);
|
|
640
641
|
const resolvedFiles = await (0, fast_glob.default)(normalizedPatterns, {
|
|
@@ -642,7 +643,10 @@ async function devCommand(options) {
|
|
|
642
643
|
absolute: false,
|
|
643
644
|
onlyFiles: true
|
|
644
645
|
});
|
|
645
|
-
const dirsToWatch = [...new Set(resolvedFiles.map((f) =>
|
|
646
|
+
const dirsToWatch = [...new Set(resolvedFiles.map((f) => {
|
|
647
|
+
const parts = f.split("/");
|
|
648
|
+
return parts.slice(0, -1).join("/");
|
|
649
|
+
}))];
|
|
646
650
|
logger$2.log(`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`);
|
|
647
651
|
const watcher = chokidar.default.watch([...resolvedFiles, ...dirsToWatch], {
|
|
648
652
|
ignored: /(^|[\/\\])\../,
|
|
@@ -713,9 +717,10 @@ var DevServer = class {
|
|
|
713
717
|
serverProcess = null;
|
|
714
718
|
isRunning = false;
|
|
715
719
|
actualPort;
|
|
716
|
-
constructor(provider, requestedPort, enableOpenApi, telescope, studio, runtime = "node") {
|
|
720
|
+
constructor(provider, requestedPort, portExplicit, enableOpenApi, telescope, studio, runtime = "node") {
|
|
717
721
|
this.provider = provider;
|
|
718
722
|
this.requestedPort = requestedPort;
|
|
723
|
+
this.portExplicit = portExplicit;
|
|
719
724
|
this.enableOpenApi = enableOpenApi;
|
|
720
725
|
this.telescope = telescope;
|
|
721
726
|
this.studio = studio;
|
|
@@ -724,8 +729,14 @@ var DevServer = class {
|
|
|
724
729
|
}
|
|
725
730
|
async start() {
|
|
726
731
|
if (this.isRunning) await this.stop();
|
|
727
|
-
|
|
728
|
-
|
|
732
|
+
if (this.portExplicit) {
|
|
733
|
+
const available = await isPortAvailable(this.requestedPort);
|
|
734
|
+
if (!available) throw new Error(`Port ${this.requestedPort} is already in use. Either stop the process using that port or omit -p/--port to auto-select an available port.`);
|
|
735
|
+
this.actualPort = this.requestedPort;
|
|
736
|
+
} else {
|
|
737
|
+
this.actualPort = await findAvailablePort(this.requestedPort);
|
|
738
|
+
if (this.actualPort !== this.requestedPort) logger$2.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
739
|
+
}
|
|
729
740
|
const serverEntryPath = (0, node_path.join)(process.cwd(), ".gkm", this.provider, "server.ts");
|
|
730
741
|
await this.createServerEntry();
|
|
731
742
|
logger$2.log(`\n✨ Starting server on port ${this.actualPort}...`);
|
|
@@ -2701,12 +2712,13 @@ program.command("build").description("Build handlers from endpoints, functions,
|
|
|
2701
2712
|
process.exit(1);
|
|
2702
2713
|
}
|
|
2703
2714
|
});
|
|
2704
|
-
program.command("dev").description("Start development server with automatic reload").option("--port <port>", "Port to run the development server on"
|
|
2715
|
+
program.command("dev").description("Start development server with automatic reload").option("-p, --port <port>", "Port to run the development server on").option("--enable-openapi", "Enable OpenAPI documentation for development server", true).action(async (options) => {
|
|
2705
2716
|
try {
|
|
2706
2717
|
const globalOptions = program.opts();
|
|
2707
2718
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
2708
2719
|
await devCommand({
|
|
2709
2720
|
port: options.port ? Number.parseInt(options.port) : 3e3,
|
|
2721
|
+
portExplicit: !!options.port,
|
|
2710
2722
|
enableOpenApi: options.enableOpenapi ?? true
|
|
2711
2723
|
});
|
|
2712
2724
|
} catch (error) {
|
|
@@ -2729,11 +2741,11 @@ program.command("api").description("Manage REST API endpoints").action(() => {
|
|
|
2729
2741
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
2730
2742
|
process.stdout.write("REST API management - coming soon\n");
|
|
2731
2743
|
});
|
|
2732
|
-
program.command("openapi").description("Generate OpenAPI specification from endpoints
|
|
2744
|
+
program.command("openapi").description("Generate OpenAPI specification from endpoints").action(async () => {
|
|
2733
2745
|
try {
|
|
2734
2746
|
const globalOptions = program.opts();
|
|
2735
2747
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
2736
|
-
await require_openapi.openapiCommand(
|
|
2748
|
+
await require_openapi.openapiCommand({});
|
|
2737
2749
|
} catch (error) {
|
|
2738
2750
|
console.error("OpenAPI generation failed:", error.message);
|
|
2739
2751
|
process.exit(1);
|