@geekmidas/cli 0.37.0 → 0.38.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/cli",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs",
5
5
  "private": false,
6
6
  "type": "module",
@@ -48,11 +48,11 @@
48
48
  "lodash.kebabcase": "^4.1.1",
49
49
  "openapi-typescript": "^7.4.2",
50
50
  "prompts": "~2.4.2",
51
+ "@geekmidas/schema": "~0.1.0",
51
52
  "@geekmidas/constructs": "~0.6.0",
53
+ "@geekmidas/envkit": "~0.5.0",
52
54
  "@geekmidas/errors": "~0.1.0",
53
- "@geekmidas/schema": "~0.1.0",
54
- "@geekmidas/logger": "~0.4.0",
55
- "@geekmidas/envkit": "~0.5.0"
55
+ "@geekmidas/logger": "~0.4.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/lodash.kebabcase": "^4.1.9",
@@ -1,7 +1,7 @@
1
1
  import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
2
- import { join } from 'node:path';
3
2
  import { tmpdir } from 'node:os';
4
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
3
+ import { join } from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
5
  import { prepareEntryCredentials } from '../index';
6
6
 
7
7
  describe('prepareEntryCredentials', () => {
@@ -179,6 +179,90 @@ export default defineWorkspace({
179
179
  });
180
180
  });
181
181
 
182
+ describe('with GKM_CONFIG_PATH set (turbo environment)', () => {
183
+ const originalEnv = process.env.GKM_CONFIG_PATH;
184
+
185
+ beforeEach(async () => {
186
+ // Create workspace structure
187
+ const gkmConfig = `
188
+ import { defineWorkspace } from '@geekmidas/cli/config';
189
+
190
+ export default defineWorkspace({
191
+ name: 'test-workspace',
192
+ apps: {
193
+ api: {
194
+ type: 'backend',
195
+ path: 'apps/api',
196
+ port: 3000,
197
+ routes: './src/endpoints/**/*.ts',
198
+ envParser: './src/config/env#envParser',
199
+ logger: './src/config/logger#logger',
200
+ },
201
+ auth: {
202
+ type: 'backend',
203
+ path: 'apps/auth',
204
+ port: 3002,
205
+ envParser: './src/config/env#envParser',
206
+ logger: './src/config/logger#logger',
207
+ },
208
+ },
209
+ services: {},
210
+ });
211
+ `;
212
+ await writeFile(join(workspaceDir, 'gkm.config.ts'), gkmConfig);
213
+
214
+ // Create apps directories
215
+ await mkdir(join(workspaceDir, 'apps', 'api', 'src'), {
216
+ recursive: true,
217
+ });
218
+ await mkdir(join(workspaceDir, 'apps', 'auth', 'src'), {
219
+ recursive: true,
220
+ });
221
+
222
+ // Create package.json files
223
+ await writeFile(
224
+ join(workspaceDir, 'apps', 'api', 'package.json'),
225
+ JSON.stringify({ name: '@test/api', version: '0.0.1' }, null, 2),
226
+ );
227
+ await writeFile(
228
+ join(workspaceDir, 'apps', 'auth', 'package.json'),
229
+ JSON.stringify({ name: '@test/auth', version: '0.0.1' }, null, 2),
230
+ );
231
+
232
+ // Set GKM_CONFIG_PATH like turbo does
233
+ process.env.GKM_CONFIG_PATH = join(workspaceDir, 'gkm.config.ts');
234
+ });
235
+
236
+ afterEach(() => {
237
+ // Restore original env
238
+ if (originalEnv === undefined) {
239
+ delete process.env.GKM_CONFIG_PATH;
240
+ } else {
241
+ process.env.GKM_CONFIG_PATH = originalEnv;
242
+ }
243
+ });
244
+
245
+ it('should read port from workspace config when GKM_CONFIG_PATH is set', async () => {
246
+ const authDir = join(workspaceDir, 'apps', 'auth');
247
+
248
+ const result = await prepareEntryCredentials({ cwd: authDir });
249
+
250
+ expect(result.resolvedPort).toBe(3002);
251
+ expect(result.credentials.PORT).toBe('3002');
252
+ expect(result.appName).toBe('auth');
253
+ });
254
+
255
+ it('should read port 3000 for api when GKM_CONFIG_PATH is set', async () => {
256
+ const apiDir = join(workspaceDir, 'apps', 'api');
257
+
258
+ const result = await prepareEntryCredentials({ cwd: apiDir });
259
+
260
+ expect(result.resolvedPort).toBe(3000);
261
+ expect(result.credentials.PORT).toBe('3000');
262
+ expect(result.appName).toBe('api');
263
+ });
264
+ });
265
+
182
266
  describe('with secrets', () => {
183
267
  beforeEach(async () => {
184
268
  // Create workspace with secrets
package/src/dev/index.ts CHANGED
@@ -1344,8 +1344,9 @@ export async function prepareEntryCredentials(options: {
1344
1344
  workspaceAppPort = appConfig.app.port;
1345
1345
  secretsRoot = appConfig.workspaceRoot;
1346
1346
  appName = appConfig.appName;
1347
- } catch {
1347
+ } catch (error) {
1348
1348
  // Not in a workspace - use defaults
1349
+ logger.log(`⚠️ Could not load workspace config: ${(error as Error).message}`);
1349
1350
  secretsRoot = findSecretsRoot(cwd);
1350
1351
  appName = getAppNameFromCwd(cwd) ?? undefined;
1351
1352
  }
@@ -1398,8 +1399,11 @@ async function entryDevCommand(options: DevOptions): Promise<void> {
1398
1399
  }
1399
1400
 
1400
1401
  // Prepare credentials (loads workspace config, secrets, injects PORT)
1402
+ // Only pass explicitPort if --port was actually specified by the user
1401
1403
  const { credentials, resolvedPort, secretsJsonPath, appName } =
1402
- await prepareEntryCredentials({ explicitPort: options.port });
1404
+ await prepareEntryCredentials({
1405
+ explicitPort: options.portExplicit ? options.port : undefined,
1406
+ });
1403
1407
 
1404
1408
  if (appName) {
1405
1409
  logger.log(`📦 App: ${appName} (port ${resolvedPort})`);