@geekmidas/cli 0.27.0 → 0.29.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/index.mjs CHANGED
@@ -26,7 +26,7 @@ import prompts from "prompts";
26
26
 
27
27
  //#region package.json
28
28
  var name = "@geekmidas/cli";
29
- var version = "0.27.0";
29
+ var version = "0.29.0";
30
30
  var description = "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs";
31
31
  var private$1 = false;
32
32
  var type = "module";
@@ -4945,21 +4945,8 @@ function generateModelsPackage(options) {
4945
4945
  version: "0.0.1",
4946
4946
  private: true,
4947
4947
  type: "module",
4948
- exports: {
4949
- ".": {
4950
- types: "./dist/index.d.ts",
4951
- import: "./dist/index.js"
4952
- },
4953
- "./*": {
4954
- types: "./dist/*.d.ts",
4955
- import: "./dist/*.js"
4956
- }
4957
- },
4958
- scripts: {
4959
- build: "tsc",
4960
- "build:watch": "tsc --watch",
4961
- typecheck: "tsc --noEmit"
4962
- },
4948
+ exports: { "./*": "./src/*.ts" },
4949
+ scripts: { typecheck: "tsc --noEmit" },
4963
4950
  dependencies: { zod: "~4.1.0" },
4964
4951
  devDependencies: { typescript: "~5.8.2" }
4965
4952
  };
@@ -6311,6 +6298,8 @@ function generateWebAppFiles(options) {
6311
6298
  },
6312
6299
  dependencies: {
6313
6300
  [modelsPackage]: "workspace:*",
6301
+ "@geekmidas/client": GEEKMIDAS_VERSIONS["@geekmidas/client"],
6302
+ "@tanstack/react-query": "~5.80.0",
6314
6303
  next: "~16.1.0",
6315
6304
  react: "~19.2.0",
6316
6305
  "react-dom": "~19.2.0"
@@ -6367,7 +6356,68 @@ export default nextConfig;
6367
6356
  ],
6368
6357
  exclude: ["node_modules"]
6369
6358
  };
6359
+ const providersTsx = `'use client';
6360
+
6361
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6362
+ import { useState } from 'react';
6363
+
6364
+ export function Providers({ children }: { children: React.ReactNode }) {
6365
+ const [queryClient] = useState(
6366
+ () =>
6367
+ new QueryClient({
6368
+ defaultOptions: {
6369
+ queries: {
6370
+ staleTime: 60 * 1000,
6371
+ },
6372
+ },
6373
+ }),
6374
+ );
6375
+
6376
+ return (
6377
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
6378
+ );
6379
+ }
6380
+ `;
6381
+ const apiIndexTs = `import { TypedFetcher } from '@geekmidas/client/fetcher';
6382
+ import { createEndpointHooks } from '@geekmidas/client/endpoint-hooks';
6383
+
6384
+ // TODO: Run 'gkm openapi' to generate typed paths from your API
6385
+ // This is a placeholder that will be replaced by the generated openapi.ts
6386
+ interface paths {
6387
+ '/health': {
6388
+ get: {
6389
+ responses: {
6390
+ 200: {
6391
+ content: {
6392
+ 'application/json': { status: string; timestamp: string };
6393
+ };
6394
+ };
6395
+ };
6396
+ };
6397
+ };
6398
+ '/users': {
6399
+ get: {
6400
+ responses: {
6401
+ 200: {
6402
+ content: {
6403
+ 'application/json': { users: Array<{ id: string; name: string }> };
6404
+ };
6405
+ };
6406
+ };
6407
+ };
6408
+ };
6409
+ }
6410
+
6411
+ const baseURL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';
6412
+
6413
+ const fetcher = new TypedFetcher<paths>({ baseURL });
6414
+
6415
+ const hooks = createEndpointHooks<paths>(fetcher.request.bind(fetcher));
6416
+
6417
+ export const api = Object.assign(fetcher.request.bind(fetcher), hooks);
6418
+ `;
6370
6419
  const layoutTsx = `import type { Metadata } from 'next';
6420
+ import { Providers } from './providers';
6371
6421
 
6372
6422
  export const metadata: Metadata = {
6373
6423
  title: '${options.name}',
@@ -6381,35 +6431,18 @@ export default function RootLayout({
6381
6431
  }) {
6382
6432
  return (
6383
6433
  <html lang="en">
6384
- <body>{children}</body>
6434
+ <body>
6435
+ <Providers>{children}</Providers>
6436
+ </body>
6385
6437
  </html>
6386
6438
  );
6387
6439
  }
6388
6440
  `;
6389
- const pageTsx = `import type { User } from '${modelsPackage}';
6441
+ const pageTsx = `import { api } from '@/api';
6390
6442
 
6391
6443
  export default async function Home() {
6392
- // Example: Fetch from API
6393
- const apiUrl = process.env.API_URL || 'http://localhost:3000';
6394
- let health = null;
6395
-
6396
- try {
6397
- const response = await fetch(\`\${apiUrl}/health\`, {
6398
- cache: 'no-store',
6399
- });
6400
- health = await response.json();
6401
- } catch (error) {
6402
- console.error('Failed to fetch health:', error);
6403
- }
6404
-
6405
- // Example: Type-safe model usage
6406
- const exampleUser: User = {
6407
- id: '123e4567-e89b-12d3-a456-426614174000',
6408
- email: 'user@example.com',
6409
- name: 'Example User',
6410
- createdAt: new Date(),
6411
- updatedAt: new Date(),
6412
- };
6444
+ // Type-safe API call using the generated client
6445
+ const health = await api('GET /health').catch(() => null);
6413
6446
 
6414
6447
  return (
6415
6448
  <main style={{ padding: '2rem', fontFamily: 'system-ui' }}>
@@ -6422,21 +6455,14 @@ export default async function Home() {
6422
6455
  {JSON.stringify(health, null, 2)}
6423
6456
  </pre>
6424
6457
  ) : (
6425
- <p>Unable to connect to API at {apiUrl}</p>
6458
+ <p>Unable to connect to API</p>
6426
6459
  )}
6427
6460
  </section>
6428
6461
 
6429
- <section style={{ marginTop: '2rem' }}>
6430
- <h2>Shared Models</h2>
6431
- <p>This user object is typed from @${options.name}/models:</p>
6432
- <pre style={{ background: '#f0f0f0', padding: '1rem', borderRadius: '8px' }}>
6433
- {JSON.stringify(exampleUser, null, 2)}
6434
- </pre>
6435
- </section>
6436
-
6437
6462
  <section style={{ marginTop: '2rem' }}>
6438
6463
  <h2>Next Steps</h2>
6439
6464
  <ul>
6465
+ <li>Run <code>gkm openapi</code> to generate typed API client</li>
6440
6466
  <li>Edit <code>apps/web/src/app/page.tsx</code> to customize this page</li>
6441
6467
  <li>Add API routes in <code>apps/api/src/endpoints/</code></li>
6442
6468
  <li>Define shared schemas in <code>packages/models/src/</code></li>
@@ -6446,11 +6472,8 @@ export default async function Home() {
6446
6472
  );
6447
6473
  }
6448
6474
  `;
6449
- const envLocal = `# API URL (injected automatically in workspace mode)
6450
- API_URL=http://localhost:3000
6451
-
6452
- # Other environment variables
6453
- # NEXT_PUBLIC_API_URL=http://localhost:3000
6475
+ const envLocal = `# API URL for client-side requests
6476
+ NEXT_PUBLIC_API_URL=http://localhost:3000
6454
6477
  `;
6455
6478
  const gitignore = `.next/
6456
6479
  node_modules/
@@ -6474,10 +6497,18 @@ node_modules/
6474
6497
  path: "apps/web/src/app/layout.tsx",
6475
6498
  content: layoutTsx
6476
6499
  },
6500
+ {
6501
+ path: "apps/web/src/app/providers.tsx",
6502
+ content: providersTsx
6503
+ },
6477
6504
  {
6478
6505
  path: "apps/web/src/app/page.tsx",
6479
6506
  content: pageTsx
6480
6507
  },
6508
+ {
6509
+ path: "apps/web/src/api/index.ts",
6510
+ content: apiIndexTs
6511
+ },
6481
6512
  {
6482
6513
  path: "apps/web/.env.local",
6483
6514
  content: envLocal
@@ -6789,6 +6820,28 @@ async function initCommand(projectName, options = {}) {
6789
6820
  });
6790
6821
  } catch {}
6791
6822
  }
6823
+ console.log("\nšŸ“¦ Initializing git repository...\n");
6824
+ try {
6825
+ execSync("git init", {
6826
+ cwd: targetDir,
6827
+ stdio: "pipe"
6828
+ });
6829
+ execSync("git branch -M main", {
6830
+ cwd: targetDir,
6831
+ stdio: "pipe"
6832
+ });
6833
+ execSync("git add .", {
6834
+ cwd: targetDir,
6835
+ stdio: "pipe"
6836
+ });
6837
+ execSync("git commit -m \"šŸŽ‰ Project created with @geekmidas/toolbox\"", {
6838
+ cwd: targetDir,
6839
+ stdio: "pipe"
6840
+ });
6841
+ console.log(" Initialized git repository on branch main");
6842
+ } catch {
6843
+ console.log(" Could not initialize git repository (git may not be installed)");
6844
+ }
6792
6845
  printNextSteps(name$1, templateOptions, pkgManager);
6793
6846
  }
6794
6847
  /**