@geekmidas/cli 0.0.26 → 0.2.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.
Files changed (121) hide show
  1. package/FUNCTION_CRON_SUPPORT.md +266 -0
  2. package/README.md +84 -17
  3. package/dist/CronGenerator-1PflEYe2.cjs +60 -0
  4. package/dist/CronGenerator-1PflEYe2.cjs.map +1 -0
  5. package/dist/CronGenerator-DXRfHQcV.mjs +54 -0
  6. package/dist/CronGenerator-DXRfHQcV.mjs.map +1 -0
  7. package/dist/EndpointGenerator-BbGrDiCP.cjs +264 -0
  8. package/dist/EndpointGenerator-BbGrDiCP.cjs.map +1 -0
  9. package/dist/EndpointGenerator-BmZ9BxbO.mjs +258 -0
  10. package/dist/EndpointGenerator-BmZ9BxbO.mjs.map +1 -0
  11. package/dist/FunctionGenerator-Clw64SwQ.cjs +59 -0
  12. package/dist/FunctionGenerator-Clw64SwQ.cjs.map +1 -0
  13. package/dist/FunctionGenerator-DOEB_yPh.mjs +53 -0
  14. package/dist/FunctionGenerator-DOEB_yPh.mjs.map +1 -0
  15. package/dist/Generator-CDoEXCDg.cjs +47 -0
  16. package/dist/Generator-CDoEXCDg.cjs.map +1 -0
  17. package/dist/Generator-UanJW0_V.mjs +41 -0
  18. package/dist/Generator-UanJW0_V.mjs.map +1 -0
  19. package/dist/SubscriberGenerator-BfMZCVNy.cjs +204 -0
  20. package/dist/SubscriberGenerator-BfMZCVNy.cjs.map +1 -0
  21. package/dist/SubscriberGenerator-D2u00NI3.mjs +198 -0
  22. package/dist/SubscriberGenerator-D2u00NI3.mjs.map +1 -0
  23. package/dist/build/index.cjs +12 -0
  24. package/dist/build/index.mjs +12 -0
  25. package/dist/build/manifests.cjs +3 -0
  26. package/dist/build/manifests.mjs +3 -0
  27. package/dist/build/providerResolver.cjs +5 -0
  28. package/dist/build/providerResolver.mjs +3 -0
  29. package/dist/build/types.cjs +0 -0
  30. package/dist/build/types.mjs +0 -0
  31. package/dist/build-BBhlEjf5.cjs +89 -0
  32. package/dist/build-BBhlEjf5.cjs.map +1 -0
  33. package/dist/build-kY-lG30Q.mjs +83 -0
  34. package/dist/build-kY-lG30Q.mjs.map +1 -0
  35. package/dist/config-D1EpSGk6.cjs +36 -0
  36. package/dist/config-D1EpSGk6.cjs.map +1 -0
  37. package/dist/config-U-mdW-7Y.mjs +30 -0
  38. package/dist/config-U-mdW-7Y.mjs.map +1 -0
  39. package/dist/config.cjs +1 -1
  40. package/dist/config.mjs +1 -1
  41. package/dist/generators/CronGenerator.cjs +4 -0
  42. package/dist/generators/CronGenerator.mjs +4 -0
  43. package/dist/generators/EndpointGenerator.cjs +4 -0
  44. package/dist/generators/EndpointGenerator.mjs +4 -0
  45. package/dist/generators/FunctionGenerator.cjs +4 -0
  46. package/dist/generators/FunctionGenerator.mjs +4 -0
  47. package/dist/generators/Generator.cjs +3 -0
  48. package/dist/generators/Generator.mjs +3 -0
  49. package/dist/generators/SubscriberGenerator.cjs +4 -0
  50. package/dist/generators/SubscriberGenerator.mjs +4 -0
  51. package/dist/generators/index.cjs +12 -0
  52. package/dist/generators/index.mjs +8 -0
  53. package/dist/generators-CEKtVh81.cjs +0 -0
  54. package/dist/generators-CsLujGXs.mjs +0 -0
  55. package/dist/index.cjs +71 -25
  56. package/dist/index.cjs.map +1 -0
  57. package/dist/index.mjs +71 -25
  58. package/dist/index.mjs.map +1 -0
  59. package/dist/manifests-BrJXpHrf.mjs +21 -0
  60. package/dist/manifests-BrJXpHrf.mjs.map +1 -0
  61. package/dist/manifests-D0saShvH.cjs +27 -0
  62. package/dist/manifests-D0saShvH.cjs.map +1 -0
  63. package/dist/{openapi-CksVdkh2.mjs → openapi-BQx3_JbM.mjs} +8 -6
  64. package/dist/openapi-BQx3_JbM.mjs.map +1 -0
  65. package/dist/{openapi-D4QQJUPY.cjs → openapi-CMLr04cz.cjs} +9 -7
  66. package/dist/openapi-CMLr04cz.cjs.map +1 -0
  67. package/dist/{openapi-react-query-DpT3XHFC.mjs → openapi-react-query-DbrWwQzb.mjs} +5 -3
  68. package/dist/openapi-react-query-DbrWwQzb.mjs.map +1 -0
  69. package/dist/{openapi-react-query-C1JLYUOs.cjs → openapi-react-query-Dvjqx_Eo.cjs} +5 -3
  70. package/dist/openapi-react-query-Dvjqx_Eo.cjs.map +1 -0
  71. package/dist/openapi-react-query.cjs +1 -1
  72. package/dist/openapi-react-query.mjs +1 -1
  73. package/dist/openapi.cjs +4 -3
  74. package/dist/openapi.mjs +4 -3
  75. package/dist/providerResolver-B_TjNF0_.mjs +96 -0
  76. package/dist/providerResolver-B_TjNF0_.mjs.map +1 -0
  77. package/dist/providerResolver-DgvzNfP4.cjs +114 -0
  78. package/dist/providerResolver-DgvzNfP4.cjs.map +1 -0
  79. package/examples/cron-example.ts +45 -0
  80. package/examples/function-example.ts +40 -0
  81. package/examples/gkm.config.json +22 -0
  82. package/examples/gkm.minimal.config.json +7 -0
  83. package/examples/gkm.production.config.json +27 -0
  84. package/examples/logger.ts +1 -1
  85. package/package.json +38 -14
  86. package/src/__tests__/config.spec.ts +110 -0
  87. package/src/__tests__/openapi-react-query.spec.ts +506 -0
  88. package/src/__tests__/openapi.spec.ts +362 -0
  89. package/src/__tests__/test-helpers.ts +180 -0
  90. package/src/build/__tests__/index-new.spec.ts +577 -0
  91. package/src/build/index.ts +197 -0
  92. package/src/build/manifests.ts +35 -0
  93. package/src/build/providerResolver.ts +184 -0
  94. package/src/build/types.ts +37 -0
  95. package/src/config.ts +14 -6
  96. package/src/generators/CronGenerator.ts +98 -0
  97. package/src/generators/EndpointGenerator.ts +389 -0
  98. package/src/generators/FunctionGenerator.ts +97 -0
  99. package/src/generators/Generator.ts +95 -0
  100. package/src/generators/SubscriberGenerator.ts +271 -0
  101. package/src/generators/__tests__/CronGenerator.spec.ts +445 -0
  102. package/src/generators/__tests__/EndpointGenerator.spec.ts +394 -0
  103. package/src/generators/__tests__/FunctionGenerator.spec.ts +256 -0
  104. package/src/generators/__tests__/SubscriberGenerator.spec.ts +341 -0
  105. package/src/generators/index.ts +9 -0
  106. package/src/index.ts +57 -22
  107. package/src/openapi-react-query.ts +2 -1
  108. package/src/openapi.ts +5 -4
  109. package/src/types.ts +91 -2
  110. package/dist/build-BTggTCYL.cjs +0 -176
  111. package/dist/build-Ca4P6_lY.mjs +0 -170
  112. package/dist/build.cjs +0 -5
  113. package/dist/build.mjs +0 -5
  114. package/dist/config-BNqUMsvc.cjs +0 -24
  115. package/dist/config-BciAdY6_.mjs +0 -18
  116. package/dist/loadEndpoints-BBIavB9h.cjs +0 -37
  117. package/dist/loadEndpoints-DAZ53Og2.mjs +0 -31
  118. package/dist/loadEndpoints.cjs +0 -3
  119. package/dist/loadEndpoints.mjs +0 -3
  120. package/src/build.ts +0 -305
  121. package/src/loadEndpoints.ts +0 -48
@@ -0,0 +1,114 @@
1
+
2
+ //#region src/build/providerResolver.ts
3
+ /**
4
+ * Resolves provider configuration from the new simplified system
5
+ * to the internal legacy format for backward compatibility
6
+ */
7
+ function resolveProviders(config, options) {
8
+ const providers = [];
9
+ let enableOpenApi = options.enableOpenApi || false;
10
+ if (options.providers) return {
11
+ providers: options.providers,
12
+ enableOpenApi
13
+ };
14
+ if (options.provider) {
15
+ const resolvedProviders = resolveMainProvider(options.provider, config.providers);
16
+ providers.push(...resolvedProviders.providers);
17
+ enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
18
+ } else if (config.providers) {
19
+ const resolvedProviders = resolveAllConfiguredProviders(config.providers);
20
+ providers.push(...resolvedProviders.providers);
21
+ enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
22
+ } else providers.push("aws-apigatewayv2", "aws-lambda");
23
+ return {
24
+ providers: [...new Set(providers)],
25
+ enableOpenApi
26
+ };
27
+ }
28
+ function resolveMainProvider(mainProvider, providersConfig) {
29
+ const providers = [];
30
+ let enableOpenApi = false;
31
+ if (mainProvider === "aws") {
32
+ const awsConfig = providersConfig?.aws;
33
+ if (awsConfig?.apiGateway) {
34
+ if (isEnabled(awsConfig.apiGateway.v1)) providers.push("aws-apigatewayv1");
35
+ if (isEnabled(awsConfig.apiGateway.v2)) providers.push("aws-apigatewayv2");
36
+ } else providers.push("aws-apigatewayv2");
37
+ if (awsConfig?.lambda) {
38
+ if (isEnabled(awsConfig.lambda.functions) || isEnabled(awsConfig.lambda.crons)) providers.push("aws-lambda");
39
+ } else providers.push("aws-lambda");
40
+ } else if (mainProvider === "server") {
41
+ providers.push("server");
42
+ const serverConfig = providersConfig?.server;
43
+ if (typeof serverConfig === "object" && serverConfig?.enableOpenApi) enableOpenApi = true;
44
+ }
45
+ return {
46
+ providers,
47
+ enableOpenApi
48
+ };
49
+ }
50
+ function resolveAllConfiguredProviders(providersConfig) {
51
+ const providers = [];
52
+ let enableOpenApi = false;
53
+ if (providersConfig.aws) {
54
+ const awsProviders = resolveMainProvider("aws", providersConfig);
55
+ providers.push(...awsProviders.providers);
56
+ }
57
+ if (providersConfig.server && isEnabled(providersConfig.server)) {
58
+ providers.push("server");
59
+ if (typeof providersConfig.server === "object" && providersConfig.server.enableOpenApi) enableOpenApi = true;
60
+ }
61
+ return {
62
+ providers,
63
+ enableOpenApi
64
+ };
65
+ }
66
+ function isEnabled(config) {
67
+ if (config === void 0) return false;
68
+ if (typeof config === "boolean") return config;
69
+ return config.enabled !== false;
70
+ }
71
+ /**
72
+ * Gets configuration for a specific AWS service
73
+ */
74
+ function getAWSServiceConfig(config, service, subService) {
75
+ const awsConfig = config.providers?.aws;
76
+ if (!awsConfig) return void 0;
77
+ if (service === "apiGateway" && awsConfig.apiGateway) {
78
+ const apiConfig = subService ? awsConfig.apiGateway[subService] : void 0;
79
+ return typeof apiConfig === "object" ? apiConfig : void 0;
80
+ }
81
+ if (service === "lambda" && awsConfig.lambda) {
82
+ const lambdaConfig = subService ? awsConfig.lambda[subService] : void 0;
83
+ return typeof lambdaConfig === "object" ? lambdaConfig : void 0;
84
+ }
85
+ return void 0;
86
+ }
87
+ /**
88
+ * Gets server configuration
89
+ */
90
+ function getServerConfig(config) {
91
+ const serverConfig = config.providers?.server;
92
+ return typeof serverConfig === "object" ? serverConfig : void 0;
93
+ }
94
+
95
+ //#endregion
96
+ Object.defineProperty(exports, 'getAWSServiceConfig', {
97
+ enumerable: true,
98
+ get: function () {
99
+ return getAWSServiceConfig;
100
+ }
101
+ });
102
+ Object.defineProperty(exports, 'getServerConfig', {
103
+ enumerable: true,
104
+ get: function () {
105
+ return getServerConfig;
106
+ }
107
+ });
108
+ Object.defineProperty(exports, 'resolveProviders', {
109
+ enumerable: true,
110
+ get: function () {
111
+ return resolveProviders;
112
+ }
113
+ });
114
+ //# sourceMappingURL=providerResolver-DgvzNfP4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerResolver-DgvzNfP4.cjs","names":["config: GkmConfig","options: BuildOptions","providers: LegacyProvider[]","mainProvider: MainProvider","providersConfig?: ProvidersConfig","providersConfig: ProvidersConfig","config:\n | boolean\n | AWSApiGatewayConfig\n | AWSLambdaConfig\n | ServerConfig\n | undefined","service: 'apiGateway' | 'lambda'","subService?: 'v1' | 'v2' | 'functions' | 'crons'"],"sources":["../src/build/providerResolver.ts"],"sourcesContent":["import type {\n AWSApiGatewayConfig,\n AWSLambdaConfig,\n BuildOptions,\n GkmConfig,\n LegacyProvider,\n MainProvider,\n ProvidersConfig,\n ServerConfig,\n} from '../types';\n\nexport interface ResolvedProviders {\n providers: LegacyProvider[];\n enableOpenApi: boolean;\n}\n\n/**\n * Resolves provider configuration from the new simplified system\n * to the internal legacy format for backward compatibility\n */\nexport function resolveProviders(\n config: GkmConfig,\n options: BuildOptions,\n): ResolvedProviders {\n const providers: LegacyProvider[] = [];\n let enableOpenApi = options.enableOpenApi || false;\n\n // Handle legacy providers option (deprecated)\n if (options.providers) {\n return {\n providers: options.providers,\n enableOpenApi,\n };\n }\n\n // Handle new provider option\n if (options.provider) {\n const resolvedProviders = resolveMainProvider(\n options.provider,\n config.providers,\n );\n providers.push(...resolvedProviders.providers);\n enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n }\n // Default: build all configured providers\n else if (config.providers) {\n const resolvedProviders = resolveAllConfiguredProviders(config.providers);\n providers.push(...resolvedProviders.providers);\n enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n }\n // Fallback: use default AWS configuration\n else {\n providers.push('aws-apigatewayv2', 'aws-lambda');\n }\n\n return {\n providers: [...new Set(providers)], // Remove duplicates\n enableOpenApi,\n };\n}\n\nfunction resolveMainProvider(\n mainProvider: MainProvider,\n providersConfig?: ProvidersConfig,\n): ResolvedProviders {\n const providers: LegacyProvider[] = [];\n let enableOpenApi = false;\n\n if (mainProvider === 'aws') {\n const awsConfig = providersConfig?.aws;\n\n // Resolve API Gateway providers\n if (awsConfig?.apiGateway) {\n if (isEnabled(awsConfig.apiGateway.v1)) {\n providers.push('aws-apigatewayv1');\n }\n if (isEnabled(awsConfig.apiGateway.v2)) {\n providers.push('aws-apigatewayv2');\n }\n } else {\n // Default: enable v2 if no specific config\n providers.push('aws-apigatewayv2');\n }\n\n // Resolve Lambda providers\n if (awsConfig?.lambda) {\n if (\n isEnabled(awsConfig.lambda.functions) ||\n isEnabled(awsConfig.lambda.crons)\n ) {\n providers.push('aws-lambda');\n }\n } else {\n // Default: enable lambda if no specific config\n providers.push('aws-lambda');\n }\n } else if (mainProvider === 'server') {\n providers.push('server');\n const serverConfig = providersConfig?.server;\n\n if (typeof serverConfig === 'object' && serverConfig?.enableOpenApi) {\n enableOpenApi = true;\n }\n }\n\n return { providers, enableOpenApi };\n}\n\nfunction resolveAllConfiguredProviders(\n providersConfig: ProvidersConfig,\n): ResolvedProviders {\n const providers: LegacyProvider[] = [];\n let enableOpenApi = false;\n\n // AWS providers\n if (providersConfig.aws) {\n const awsProviders = resolveMainProvider('aws', providersConfig);\n providers.push(...awsProviders.providers);\n }\n\n // Server provider\n if (providersConfig.server && isEnabled(providersConfig.server)) {\n providers.push('server');\n if (\n typeof providersConfig.server === 'object' &&\n providersConfig.server.enableOpenApi\n ) {\n enableOpenApi = true;\n }\n }\n\n return { providers, enableOpenApi };\n}\n\nfunction isEnabled(\n config:\n | boolean\n | AWSApiGatewayConfig\n | AWSLambdaConfig\n | ServerConfig\n | undefined,\n): boolean {\n if (config === undefined) return false;\n if (typeof config === 'boolean') return config;\n return config.enabled !== false; // Default to true if enabled is not explicitly false\n}\n\n/**\n * Gets configuration for a specific AWS service\n */\nexport function getAWSServiceConfig<\n T extends AWSApiGatewayConfig | AWSLambdaConfig,\n>(\n config: GkmConfig,\n service: 'apiGateway' | 'lambda',\n subService?: 'v1' | 'v2' | 'functions' | 'crons',\n): T | undefined {\n const awsConfig = config.providers?.aws;\n if (!awsConfig) return undefined;\n\n if (service === 'apiGateway' && awsConfig.apiGateway) {\n const apiConfig = subService\n ? awsConfig.apiGateway[subService as 'v1' | 'v2']\n : undefined;\n return typeof apiConfig === 'object' ? (apiConfig as T) : undefined;\n }\n\n if (service === 'lambda' && awsConfig.lambda) {\n const lambdaConfig = subService\n ? awsConfig.lambda[subService as 'functions' | 'crons']\n : undefined;\n return typeof lambdaConfig === 'object' ? (lambdaConfig as T) : undefined;\n }\n\n return undefined;\n}\n\n/**\n * Gets server configuration\n */\nexport function getServerConfig(config: GkmConfig): ServerConfig | undefined {\n const serverConfig = config.providers?.server;\n return typeof serverConfig === 'object' ? serverConfig : undefined;\n}\n"],"mappings":";;;;;;AAoBA,SAAgB,iBACdA,QACAC,SACmB;CACnB,MAAMC,YAA8B,CAAE;CACtC,IAAI,gBAAgB,QAAQ,iBAAiB;AAG7C,KAAI,QAAQ,UACV,QAAO;EACL,WAAW,QAAQ;EACnB;CACD;AAIH,KAAI,QAAQ,UAAU;EACpB,MAAM,oBAAoB,oBACxB,QAAQ,UACR,OAAO,UACR;AACD,YAAU,KAAK,GAAG,kBAAkB,UAAU;AAC9C,kBAAgB,kBAAkB,iBAAiB;CACpD,WAEQ,OAAO,WAAW;EACzB,MAAM,oBAAoB,8BAA8B,OAAO,UAAU;AACzE,YAAU,KAAK,GAAG,kBAAkB,UAAU;AAC9C,kBAAgB,kBAAkB,iBAAiB;CACpD,MAGC,WAAU,KAAK,oBAAoB,aAAa;AAGlD,QAAO;EACL,WAAW,CAAC,GAAG,IAAI,IAAI,UAAW;EAClC;CACD;AACF;AAED,SAAS,oBACPC,cACAC,iBACmB;CACnB,MAAMF,YAA8B,CAAE;CACtC,IAAI,gBAAgB;AAEpB,KAAI,iBAAiB,OAAO;EAC1B,MAAM,YAAY,iBAAiB;AAGnC,MAAI,WAAW,YAAY;AACzB,OAAI,UAAU,UAAU,WAAW,GAAG,CACpC,WAAU,KAAK,mBAAmB;AAEpC,OAAI,UAAU,UAAU,WAAW,GAAG,CACpC,WAAU,KAAK,mBAAmB;EAErC,MAEC,WAAU,KAAK,mBAAmB;AAIpC,MAAI,WAAW,QACb;OACE,UAAU,UAAU,OAAO,UAAU,IACrC,UAAU,UAAU,OAAO,MAAM,CAEjC,WAAU,KAAK,aAAa;EAC7B,MAGD,WAAU,KAAK,aAAa;CAE/B,WAAU,iBAAiB,UAAU;AACpC,YAAU,KAAK,SAAS;EACxB,MAAM,eAAe,iBAAiB;AAEtC,aAAW,iBAAiB,YAAY,cAAc,cACpD,iBAAgB;CAEnB;AAED,QAAO;EAAE;EAAW;CAAe;AACpC;AAED,SAAS,8BACPG,iBACmB;CACnB,MAAMH,YAA8B,CAAE;CACtC,IAAI,gBAAgB;AAGpB,KAAI,gBAAgB,KAAK;EACvB,MAAM,eAAe,oBAAoB,OAAO,gBAAgB;AAChE,YAAU,KAAK,GAAG,aAAa,UAAU;CAC1C;AAGD,KAAI,gBAAgB,UAAU,UAAU,gBAAgB,OAAO,EAAE;AAC/D,YAAU,KAAK,SAAS;AACxB,aACS,gBAAgB,WAAW,YAClC,gBAAgB,OAAO,cAEvB,iBAAgB;CAEnB;AAED,QAAO;EAAE;EAAW;CAAe;AACpC;AAED,SAAS,UACPI,QAMS;AACT,KAAI,kBAAsB,QAAO;AACjC,YAAW,WAAW,UAAW,QAAO;AACxC,QAAO,OAAO,YAAY;AAC3B;;;;AAKD,SAAgB,oBAGdN,QACAO,SACAC,YACe;CACf,MAAM,YAAY,OAAO,WAAW;AACpC,MAAK,UAAW;AAEhB,KAAI,YAAY,gBAAgB,UAAU,YAAY;EACpD,MAAM,YAAY,aACd,UAAU,WAAW;AAEzB,gBAAc,cAAc,WAAY;CACzC;AAED,KAAI,YAAY,YAAY,UAAU,QAAQ;EAC5C,MAAM,eAAe,aACjB,UAAU,OAAO;AAErB,gBAAc,iBAAiB,WAAY;CAC5C;AAED;AACD;;;;AAKD,SAAgB,gBAAgBR,QAA6C;CAC3E,MAAM,eAAe,OAAO,WAAW;AACvC,eAAc,iBAAiB,WAAW;AAC3C"}
@@ -0,0 +1,45 @@
1
+ import { cron } from '@geekmidas/constructs/crons';
2
+
3
+ /**
4
+ * Example cron that generates a daily report at 9 AM UTC
5
+ */
6
+ export const dailyReport = cron
7
+ .schedule('cron(0 9 * * ? *)')
8
+ .timeout(600000) // 10 minutes
9
+ .handle(async ({ services, logger }) => {
10
+ logger.info('Generating daily report');
11
+
12
+ const reportDate = new Date().toISOString().split('T')[0];
13
+
14
+ // Generate report logic here
15
+ const reportData = {
16
+ date: reportDate,
17
+ totalOrders: 150,
18
+ totalRevenue: 12500.0,
19
+ topProducts: [
20
+ { id: 'prod-1', name: 'Widget A', sales: 45 },
21
+ { id: 'prod-2', name: 'Widget B', sales: 32 },
22
+ ],
23
+ };
24
+
25
+ logger.info('Daily report generated', reportData);
26
+
27
+ return reportData;
28
+ });
29
+
30
+ /**
31
+ * Example cron that runs every hour
32
+ */
33
+ export const hourlyCleanup = cron
34
+ .schedule('rate(1 hour)')
35
+ .timeout(300000) // 5 minutes
36
+ .handle(async ({ services, logger }) => {
37
+ logger.info('Running hourly cleanup');
38
+
39
+ // Cleanup logic here
40
+ const itemsCleaned = 42;
41
+
42
+ logger.info(`Cleaned ${itemsCleaned} items`);
43
+
44
+ return { itemsCleaned };
45
+ });
@@ -0,0 +1,40 @@
1
+ import { f } from '@geekmidas/constructs/functions';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Example function that processes an order
6
+ */
7
+ export const processOrder = f
8
+ .input(
9
+ z.object({
10
+ orderId: z.string(),
11
+ items: z.array(
12
+ z.object({
13
+ id: z.string(),
14
+ quantity: z.number().int().positive(),
15
+ }),
16
+ ),
17
+ }),
18
+ )
19
+ .output(
20
+ z.object({
21
+ orderId: z.string(),
22
+ status: z.enum(['processing', 'completed', 'failed']),
23
+ processedAt: z.string().datetime(),
24
+ }),
25
+ )
26
+ .timeout(300000) // 5 minutes
27
+ .handle(async ({ input, services, logger }) => {
28
+ logger.info(`Processing order ${input.orderId}`);
29
+
30
+ // Process order logic here
31
+ for (const item of input.items) {
32
+ logger.info(`Processing item ${item.id}, quantity: ${item.quantity}`);
33
+ }
34
+
35
+ return {
36
+ orderId: input.orderId,
37
+ status: 'completed' as const,
38
+ processedAt: new Date().toISOString(),
39
+ };
40
+ });
@@ -0,0 +1,22 @@
1
+ {
2
+ "routes": "./src/endpoints/**/*.ts",
3
+ "functions": "./src/functions/**/*.ts",
4
+ "crons": "./src/crons/**/*.ts",
5
+ "envParser": "./src/env.ts#envParser",
6
+ "logger": "./src/logger.ts#logger",
7
+ "providers": {
8
+ "aws": {
9
+ "apiGateway": {
10
+ "v1": false,
11
+ "v2": true
12
+ },
13
+ "lambda": {
14
+ "functions": true,
15
+ "crons": true
16
+ }
17
+ },
18
+ "server": {
19
+ "enableOpenApi": true
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "routes": "./src/endpoints/**/*.ts",
3
+ "functions": "./src/functions/**/*.ts",
4
+ "crons": "./src/crons/**/*.ts",
5
+ "envParser": "./src/env.ts#envParser",
6
+ "logger": "./src/logger.ts#logger"
7
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "routes": "./src/endpoints/**/*.ts",
3
+ "functions": "./src/functions/**/*.ts",
4
+ "crons": "./src/crons/**/*.ts",
5
+ "envParser": "./src/env.ts#envParser",
6
+ "logger": "./src/logger.ts#logger",
7
+ "providers": {
8
+ "aws": {
9
+ "apiGateway": {
10
+ "v2": {
11
+ "enabled": true,
12
+ "outputDir": "dist/api-gateway"
13
+ }
14
+ },
15
+ "lambda": {
16
+ "functions": {
17
+ "enabled": true,
18
+ "outputDir": "dist/functions"
19
+ },
20
+ "crons": {
21
+ "enabled": true,
22
+ "outputDir": "dist/crons"
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
@@ -1,4 +1,4 @@
1
- import { ConsoleLogger } from '@geekmidas/api/logger';
1
+ import { ConsoleLogger } from '@geekmidas/logger/console';
2
2
 
3
3
  // Create a console logger instance
4
4
  export const logger = new ConsoleLogger({
package/package.json CHANGED
@@ -1,26 +1,50 @@
1
1
  {
2
2
  "name": "@geekmidas/cli",
3
- "version": "0.0.26",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.cjs"
11
+ },
12
+ "./openapi": {
13
+ "types": "./dist/openapi.d.ts",
14
+ "import": "./dist/openapi.mjs",
15
+ "require": "./dist/openapi.cjs"
16
+ },
17
+ "./openapi-react-query": {
18
+ "types": "./dist/openapi-react-query.d.ts",
19
+ "import": "./dist/openapi-react-query.mjs",
20
+ "require": "./dist/openapi-react-query.cjs"
21
+ }
22
+ },
6
23
  "bin": {
7
24
  "gkm": "./dist/index.cjs"
8
25
  },
9
- "publishConfig": {
10
- "registry": "https://registry.npmjs.org/",
11
- "access": "public"
12
- },
13
26
  "dependencies": {
14
- "commander": "~14.0.0",
15
- "lodash.get": "~4.4.2",
16
- "lodash.set": "~4.3.2",
17
- "fast-glob": "~3.3.3"
18
- },
19
- "peerDependencies": {
20
- "@geekmidas/api": "0.0.51"
27
+ "@apidevtools/swagger-parser": "^10.1.0",
28
+ "commander": "^12.1.0",
29
+ "fast-glob": "^3.3.2",
30
+ "lodash.kebabcase": "^4.1.1",
31
+ "openapi-typescript": "^7.4.2",
32
+ "@geekmidas/constructs": "0.0.1",
33
+ "@geekmidas/schema": "0.0.1",
34
+ "@geekmidas/envkit": "0.0.7"
21
35
  },
22
36
  "devDependencies": {
23
- "@types/lodash.get": "~4.4.9",
24
- "@types/lodash.set": "~4.3.9"
37
+ "@types/lodash.kebabcase": "^4.1.9",
38
+ "typescript": "^5.8.2",
39
+ "vitest": "^3.2.4",
40
+ "zod": "^3.23.8",
41
+ "@geekmidas/testkit": "0.0.16",
42
+ "@geekmidas/logger": "0.0.1"
43
+ },
44
+ "scripts": {
45
+ "ts": "tsc --noEmit --skipLibCheck src/**/*.ts",
46
+ "test": "vitest",
47
+ "test:once": "vitest run",
48
+ "test:coverage": "vitest run --coverage"
25
49
  }
26
50
  }
@@ -0,0 +1,110 @@
1
+ import { writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
4
+ import { loadConfig } from '../config';
5
+ import { cleanupDir, createTempDir } from './test-helpers';
6
+
7
+ describe('loadConfig', () => {
8
+ let tempDir: string;
9
+ let originalCwd: string;
10
+
11
+ beforeEach(async () => {
12
+ tempDir = await createTempDir();
13
+ originalCwd = process.cwd();
14
+ process.chdir(tempDir);
15
+ });
16
+
17
+ afterEach(async () => {
18
+ process.chdir(originalCwd);
19
+ await cleanupDir(tempDir);
20
+ });
21
+
22
+ it('should load configuration from gkm.config.ts', async () => {
23
+ const configContent = `
24
+ export default {
25
+ routes: './src/endpoints/**/*.ts',
26
+ functions: './src/functions/**/*.ts',
27
+ crons: './src/crons/**/*.ts',
28
+ envParser: './src/config/env',
29
+ logger: './src/config/logger',
30
+ };
31
+ `;
32
+ await writeFile(join(tempDir, 'gkm.config.ts'), configContent);
33
+
34
+ const config = await loadConfig();
35
+
36
+ expect(config).toEqual({
37
+ routes: './src/endpoints/**/*.ts',
38
+ functions: './src/functions/**/*.ts',
39
+ crons: './src/crons/**/*.ts',
40
+ envParser: './src/config/env',
41
+ logger: './src/config/logger',
42
+ });
43
+ });
44
+
45
+ it('should load configuration from gkm.config.js', async () => {
46
+ const configContent = `
47
+ module.exports = {
48
+ routes: './api/**/*.js',
49
+ envParser: './config/environment',
50
+ logger: './config/logging',
51
+ };
52
+ `;
53
+ await writeFile(join(tempDir, 'gkm.config.js'), configContent);
54
+
55
+ const config = await loadConfig();
56
+
57
+ expect(config.routes).toBe('./api/**/*.js');
58
+ expect(config.envParser).toBe('./config/environment');
59
+ expect(config.logger).toBe('./config/logging');
60
+ });
61
+
62
+ it('should handle configuration with only envParser override', async () => {
63
+ const configContent = `
64
+ export default {
65
+ envParser: './my-env#myEnvParser',
66
+ logger: './my-logger#myLogger',
67
+ };
68
+ `;
69
+ await writeFile(join(tempDir, 'gkm.config.ts'), configContent);
70
+
71
+ const config = await loadConfig();
72
+
73
+ expect(config.envParser).toBe('./my-env#myEnvParser');
74
+ expect(config.logger).toBe('./my-logger#myLogger');
75
+ });
76
+
77
+ it('should handle malformed config file gracefully', async () => {
78
+ const invalidConfigContent = `
79
+ export default {
80
+ routes: './endpoints/**/*.ts'
81
+ // Missing comma - syntax error
82
+ functions: './functions/**/*.ts'
83
+ };
84
+ `;
85
+ await writeFile(join(tempDir, 'gkm.config.ts'), invalidConfigContent);
86
+
87
+ // Should fall back to defaults when config file has syntax errors
88
+ await expect(loadConfig()).rejects.toThrow();
89
+ });
90
+
91
+ it('should prefer .ts config over .js config', async () => {
92
+ const jsConfigContent = `
93
+ module.exports = {
94
+ routes: './js-routes/**/*.js',
95
+ };
96
+ `;
97
+ const tsConfigContent = `
98
+ export default {
99
+ routes: './ts-routes/**/*.ts',
100
+ };
101
+ `;
102
+
103
+ await writeFile(join(tempDir, 'gkm.config.js'), jsConfigContent);
104
+ await writeFile(join(tempDir, 'gkm.config.ts'), tsConfigContent);
105
+
106
+ const config = await loadConfig();
107
+
108
+ expect(config.routes).toBe('./ts-routes/**/*.ts');
109
+ });
110
+ });