@geekmidas/cli 10.0.0-alpha.45 → 10.0.0-alpha.46

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 (80) hide show
  1. package/README.md +144 -183
  2. package/dist/{OpenApiTsGenerator-B4Kj_qNU.cjs → OpenApiTsGenerator-BN0PIZxd.cjs} +17 -71
  3. package/dist/OpenApiTsGenerator-BN0PIZxd.cjs.map +1 -0
  4. package/dist/{OpenApiTsGenerator-CEh3EKN3.mjs → OpenApiTsGenerator-BzIGy8KE.mjs} +17 -71
  5. package/dist/OpenApiTsGenerator-BzIGy8KE.mjs.map +1 -0
  6. package/dist/{config-CJ-PAb7M.cjs → config-CsYSyUya.cjs} +3 -3
  7. package/dist/{config-CJ-PAb7M.cjs.map → config-CsYSyUya.cjs.map} +1 -1
  8. package/dist/{config-5watB1D0.mjs → config-D8J5rrTb.mjs} +3 -3
  9. package/dist/{config-5watB1D0.mjs.map → config-D8J5rrTb.mjs.map} +1 -1
  10. package/dist/config.cjs +2 -2
  11. package/dist/config.d.cts +2 -2
  12. package/dist/config.d.mts +2 -2
  13. package/dist/config.mjs +2 -2
  14. package/dist/{discover-BLhf7V_J.mjs → discover-Cf2jAcgF.mjs} +4 -56
  15. package/dist/discover-Cf2jAcgF.mjs.map +1 -0
  16. package/dist/{discover-B0f_kuNN.cjs → discover-DXNviAh-.cjs} +3 -79
  17. package/dist/discover-DXNviAh-.cjs.map +1 -0
  18. package/dist/{emit-Bzq7JsMP.mjs → emit-C1e8qD08.mjs} +12 -43
  19. package/dist/emit-C1e8qD08.mjs.map +1 -0
  20. package/dist/{emit-BdoPFjZf.cjs → emit-Dmc1nvdS.cjs} +11 -54
  21. package/dist/emit-Dmc1nvdS.cjs.map +1 -0
  22. package/dist/{github-D5MthUlR.mjs → github-BfpadQWQ.mjs} +3 -3
  23. package/dist/{github-D5MthUlR.mjs.map → github-BfpadQWQ.mjs.map} +1 -1
  24. package/dist/{github-BAr8WGkR.cjs → github-BrI1tv6u.cjs} +3 -3
  25. package/dist/{github-BAr8WGkR.cjs.map → github-BrI1tv6u.cjs.map} +1 -1
  26. package/dist/{index-B3PeGOQp.d.cts → index-BQhJXpaQ.d.mts} +2 -2
  27. package/dist/{index-B3PeGOQp.d.cts.map → index-BQhJXpaQ.d.mts.map} +1 -1
  28. package/dist/{index-BOyaGcCm.d.mts → index-DHJePE0y.d.cts} +2 -2
  29. package/dist/{index-BOyaGcCm.d.mts.map → index-DHJePE0y.d.cts.map} +1 -1
  30. package/dist/index.cjs +395 -660
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.mjs +397 -662
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/{migrate-BRklCm7b.mjs → migrate-B3opyC3o.mjs} +5 -5
  35. package/dist/{migrate-BRklCm7b.mjs.map → migrate-B3opyC3o.mjs.map} +1 -1
  36. package/dist/{migrate-PJi4b1ga.cjs → migrate-Dp5HFzuQ.cjs} +5 -5
  37. package/dist/{migrate-PJi4b1ga.cjs.map → migrate-Dp5HFzuQ.cjs.map} +1 -1
  38. package/dist/openapi.cjs +2 -2
  39. package/dist/openapi.d.cts +1 -1
  40. package/dist/openapi.d.mts +1 -1
  41. package/dist/openapi.mjs +2 -2
  42. package/dist/{ready-3RfHxdA0.cjs → ready-L7I68yXf.cjs} +67 -8
  43. package/dist/ready-L7I68yXf.cjs.map +1 -0
  44. package/dist/{ready-ZqOuNvKD.mjs → ready-V6Ou6-B6.mjs} +49 -8
  45. package/dist/ready-V6Ou6-B6.mjs.map +1 -0
  46. package/dist/reconcile/public.cjs +2 -4
  47. package/dist/reconcile/public.d.cts +6 -10
  48. package/dist/reconcile/public.d.cts.map +1 -1
  49. package/dist/reconcile/public.d.mts +6 -10
  50. package/dist/reconcile/public.d.mts.map +1 -1
  51. package/dist/reconcile/public.mjs +3 -3
  52. package/dist/{types-0R124hrY.d.mts → types-BbrNu83u.d.mts} +14 -109
  53. package/dist/{types-0R124hrY.d.mts.map → types-BbrNu83u.d.mts.map} +1 -1
  54. package/dist/{types-DfdYe31u.d.cts → types-DNqEsctD.d.cts} +14 -109
  55. package/dist/{types-DfdYe31u.d.cts.map → types-DNqEsctD.d.cts.map} +1 -1
  56. package/dist/vitest.cjs +1 -1
  57. package/dist/vitest.mjs +1 -1
  58. package/dist/workspace/index.cjs +1 -1
  59. package/dist/workspace/index.d.cts +2 -2
  60. package/dist/workspace/index.d.mts +2 -2
  61. package/dist/workspace/index.mjs +1 -1
  62. package/dist/{workspace-BKytVCzb.mjs → workspace-CHEC80sp.mjs} +6 -7
  63. package/dist/workspace-CHEC80sp.mjs.map +1 -0
  64. package/dist/{workspace-dV6f-3vv.cjs → workspace-D9z2ymBW.cjs} +11 -12
  65. package/dist/workspace-D9z2ymBW.cjs.map +1 -0
  66. package/dist/{workspace-RYSYtHP7.cjs → workspace-DEibcoBe.cjs} +11 -25
  67. package/dist/{workspace-RYSYtHP7.cjs.map → workspace-DEibcoBe.cjs.map} +1 -1
  68. package/dist/{workspace-DOmIhiau.mjs → workspace-DNzWgM1J.mjs} +11 -25
  69. package/dist/{workspace-DOmIhiau.mjs.map → workspace-DNzWgM1J.mjs.map} +1 -1
  70. package/package.json +14 -14
  71. package/dist/OpenApiTsGenerator-B4Kj_qNU.cjs.map +0 -1
  72. package/dist/OpenApiTsGenerator-CEh3EKN3.mjs.map +0 -1
  73. package/dist/discover-B0f_kuNN.cjs.map +0 -1
  74. package/dist/discover-BLhf7V_J.mjs.map +0 -1
  75. package/dist/emit-BdoPFjZf.cjs.map +0 -1
  76. package/dist/emit-Bzq7JsMP.mjs.map +0 -1
  77. package/dist/ready-3RfHxdA0.cjs.map +0 -1
  78. package/dist/ready-ZqOuNvKD.mjs.map +0 -1
  79. package/dist/workspace-BKytVCzb.mjs.map +0 -1
  80. package/dist/workspace-dV6f-3vv.cjs.map +0 -1
package/README.md CHANGED
@@ -186,8 +186,8 @@ topic is what puts a broker in the local plan and resolves
186
186
  ### 6. Build Handlers
187
187
 
188
188
  ```bash
189
- # Generate AWS Lambda handlers
190
- npx gkm build --provider aws-apigatewayv1
189
+ # Build for where gkm.config.ts deploys (AWS for `deploy: { default: 'sst' }`)
190
+ npx gkm build
191
191
 
192
192
  # Generate server application
193
193
  npx gkm build --provider server
@@ -311,17 +311,20 @@ Generate handlers from your endpoints.
311
311
  gkm build [options]
312
312
  ```
313
313
 
314
+ By default it builds for where the project deploys: `deploy: { default: 'sst' }`
315
+ builds for AWS, one Lambda per construct; `dokploy` (the default when nothing
316
+ is declared) builds a server.
317
+
314
318
  **Options:**
315
- - `--provider <provider>`: Target provider (default: `aws-apigatewayv1`)
316
- - `aws-apigatewayv1`: AWS API Gateway v1 Lambda handlers
317
- - `aws-apigatewayv2`: AWS API Gateway v2 Lambda handlers
319
+ - `--provider <provider>`: Override the deploy target
320
+ - `aws`: One Lambda handler per construct (API Gateway v2 for endpoints)
318
321
  - `server`: Server application with Hono
319
322
  - `--production`: Generate production-optimized bundle (server provider only)
320
323
 
321
324
  **Example:**
322
325
  ```bash
323
- # Generate AWS Lambda handlers
324
- gkm build --provider aws-apigatewayv1
326
+ # Build for where gkm.config.ts deploys
327
+ gkm build
325
328
 
326
329
  # Generate server application
327
330
  gkm build --provider server
@@ -923,15 +926,6 @@ export default defineConfig({
923
926
  registry: 'ghcr.io/myorg',
924
927
  imageName: 'my-api',
925
928
  },
926
-
927
- // For Dokploy deployments
928
- providers: {
929
- dokploy: {
930
- endpoint: 'https://dokploy.example.com',
931
- projectId: 'proj_xxx',
932
- applicationId: 'app_xxx',
933
- },
934
- },
935
929
  });
936
930
  ```
937
931
 
@@ -941,7 +935,7 @@ export default defineConfig({
941
935
 
942
936
  ### `gkm deploy:init`
943
937
 
944
- Initialize a new Dokploy deployment by creating a project and application via the Dokploy API. Automatically updates `gkm.config.ts` with the configuration.
938
+ Initialize a new Dokploy deployment by creating a project and application via the Dokploy API. Nothing is written to `gkm.config.ts`: the ids are rediscovered by name on each run and kept in the deploy state file.
945
939
 
946
940
  ```bash
947
941
  gkm deploy:init --project <name> --app <name> [options]
@@ -976,8 +970,7 @@ gkm deploy:init \
976
970
  1. Searches for existing project by name, or creates a new one
977
971
  2. Creates a new application in the project
978
972
  3. Configures registry if `--registry-id` is provided
979
- 4. Updates `gkm.config.ts` with the Dokploy configuration
980
- 5. Shows next steps for secrets and deployment
973
+ 4. Shows next steps for secrets and deployment
981
974
 
982
975
  ### `gkm deploy:list`
983
976
 
@@ -1045,21 +1038,16 @@ The following commands are planned for future releases:
1045
1038
  The `gkm.config.ts` file defines how the CLI discovers and processes your endpoints:
1046
1039
 
1047
1040
  ```typescript
1048
- // Construct types accept a string, string[], or partitioned config
1049
- type Routes = string | string[] | PartitionedRoutes;
1050
-
1051
- interface PartitionedRoutes {
1052
- paths: string | string[];
1053
- partition: (filepath: string) => string;
1054
- }
1041
+ // Construct types accept a glob string or an array of them
1042
+ type Routes = string | string[];
1055
1043
 
1056
1044
  interface GkmConfig {
1057
- routes: Routes; // Glob patterns or partitioned config
1045
+ routes: Routes; // Glob patterns
1058
1046
  envParser: string; // Path to environment parser
1059
1047
  logger: string; // Path to logger configuration
1060
- functions?: Routes; // Glob patterns or partitioned config
1061
- crons?: Routes; // Glob patterns or partitioned config
1062
- subscribers?: Routes; // Glob patterns or partitioned config
1048
+ functions?: Routes; // Glob patterns
1049
+ crons?: Routes; // Glob patterns
1050
+ subscribers?: Routes; // Glob patterns
1063
1051
  runtime?: 'node' | 'bun'; // Runtime environment (default: 'node')
1064
1052
  telescope?: boolean | TelescopeConfig; // Telescope debugging config
1065
1053
  }
@@ -1078,7 +1066,7 @@ interface TelescopeConfig {
1078
1066
 
1079
1067
  #### `routes`
1080
1068
 
1081
- Glob pattern(s) to discover endpoint files. Can be a single pattern, array of patterns, or a partitioned config:
1069
+ Glob pattern(s) to discover endpoint files. Can be a single pattern or an array of patterns:
1082
1070
 
1083
1071
  ```typescript
1084
1072
  // Single pattern
@@ -1090,19 +1078,8 @@ routes: [
1090
1078
  'src/api/**/*.ts',
1091
1079
  'src/handlers/**/*.ts'
1092
1080
  ]
1093
-
1094
- // Partitioned — groups constructs in the generated manifest
1095
- routes: {
1096
- paths: './src/endpoints/**/*.ts',
1097
- partition: (filepath) => {
1098
- const match = filepath.match(/endpoints\/([^/]+)\//);
1099
- return match?.[1] ?? 'default';
1100
- },
1101
- }
1102
1081
  ```
1103
1082
 
1104
- The same partitioned format works for `functions`, `crons`, and `subscribers`. When a `partition` callback is provided, the generated manifest groups constructs by partition name (e.g., `manifest.routes.admin`). Without it, manifest fields remain flat arrays.
1105
-
1106
1083
  #### `envParser`
1107
1084
 
1108
1085
  Path to your environment parser configuration. Supports both default and named exports.
@@ -1357,42 +1334,24 @@ interface AppSpec {
1357
1334
  }
1358
1335
  ```
1359
1336
 
1360
- ## Providers
1337
+ ## Build Targets
1361
1338
 
1362
- ### AWS API Gateway v1
1339
+ ### AWS
1363
1340
 
1364
- Generates Lambda handlers compatible with AWS API Gateway v1 (REST API).
1341
+ Generates one Lambda handler per construct. Endpoints get an API Gateway v2
1342
+ (HTTP API) adapter.
1365
1343
 
1366
1344
  ```bash
1367
- gkm build --provider aws-apigatewayv1
1368
- ```
1369
-
1370
- **Generated Handler:**
1371
- ```typescript
1372
- import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
1373
- import { myEndpoint } from '../src/routes/example.js';
1374
- import { envParser } from '../src/env.js';
1375
-
1376
- const adapter = new AmazonApiGatewayV1Endpoint(envParser, myEndpoint);
1377
-
1378
- export const handler = adapter.handler;
1379
- ```
1380
-
1381
- ### AWS API Gateway v2
1382
-
1383
- Generates Lambda handlers compatible with AWS API Gateway v2 (HTTP API).
1384
-
1385
- ```bash
1386
- gkm build --provider aws-apigatewayv2
1345
+ gkm build # with deploy: { default: 'sst' }
1346
+ gkm build --provider aws # whatever the deploy target
1387
1347
  ```
1388
1348
 
1389
1349
  **Generated Handler:**
1390
1350
  ```typescript
1391
1351
  import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
1392
- import { myEndpoint } from '../src/routes/example.js';
1393
- import { envParser } from '../src/env.js';
1352
+ import { myEndpoint } from '../../../src/routes/example.js';
1394
1353
 
1395
- const adapter = new AmazonApiGatewayV2Endpoint(envParser, myEndpoint);
1354
+ const adapter = new AmazonApiGatewayV2Endpoint(myEndpoint);
1396
1355
 
1397
1356
  export const handler = adapter.handler;
1398
1357
  ```
@@ -1434,139 +1393,141 @@ export default createApp;
1434
1393
 
1435
1394
  ## Output Structure
1436
1395
 
1437
- The CLI generates files in the `.gkm/<provider>` directory:
1396
+ Handlers are generated beside the app, in `<app>/.gkm/<target>`; the manifest
1397
+ at the workspace root, where `sst.config.ts` runs:
1438
1398
 
1439
1399
  ```
1440
- .gkm/
1441
- ├── aws-apigatewayv1/
1442
- │ ├── getUsers.ts # Individual Lambda handler
1443
- │ ├── createUser.ts # Individual Lambda handler
1444
- ├── server/
1445
- │ ├── app.ts # Server application
1446
- │ ├── endpoints.ts # Endpoint exports
1447
- ├── manifest/
1448
- │ ├── aws.ts # AWS manifest with types
1449
- │ └── server.ts # Server manifest with types
1450
- └── openapi.json # OpenAPI specification
1400
+ <root>/
1401
+ ├── .gkm/manifest/
1402
+ │ ├── aws.ts # AWS manifest with types
1403
+ │ └── server.ts # Server manifest with types
1404
+ └── apps/api/.gkm/
1405
+ ├── aws/
1406
+ │ ├── routes/getUsers.ts # One Lambda handler per endpoint
1407
+ │ ├── functions/
1408
+ │ ├── crons/
1409
+ │ ├── queues/
1410
+ │ └── subscribers/
1411
+ └── server/
1412
+ ├── app.ts # Server application
1413
+ └── endpoints.ts # Endpoint exports
1451
1414
  ```
1452
1415
 
1453
1416
  ### Build Manifest
1454
1417
 
1455
- The CLI generates TypeScript manifests with full type information in the `.gkm/manifest/` directory. These manifests export both the data and derived types for type-safe usage.
1418
+ The manifest is the application's, not an app's: the root `gkm build` builds
1419
+ every backend and writes it once, to `.gkm/manifest/aws.ts` or
1420
+ `.gkm/manifest/server.ts` at the workspace root. An app's own build writes no
1421
+ manifest. Every handler path in it is relative to the workspace root. `gkm init`
1422
+ adds a root tsconfig alias for the manifest, `@<project>/manifest`.
1456
1423
 
1457
- #### AWS Manifest (`.gkm/manifest/aws.ts`)
1424
+ It exports two values — every declared construct keyed by id, and the backends
1425
+ the build resolved — and the types derived from them:
1458
1426
 
1459
1427
  ```typescript
1460
- export const manifest = {
1461
- routes: [
1462
- {
1463
- path: '/users',
1464
- method: 'GET',
1465
- handler: '.gkm/aws-apigatewayv1/getUsers.handler',
1466
- authorizer: 'jwt',
1467
- },
1468
- {
1469
- path: '/users',
1470
- method: 'POST',
1471
- handler: '.gkm/aws-apigatewayv1/createUser.handler',
1472
- authorizer: 'jwt',
1473
- },
1474
- ],
1475
- functions: [
1476
- {
1477
- name: 'processData',
1478
- handler: '.gkm/aws-lambda/functions/processData.handler',
1479
- timeout: 60,
1480
- memorySize: 256,
1481
- },
1482
- ],
1483
- crons: [
1484
- {
1485
- name: 'dailyCleanup',
1486
- handler: '.gkm/aws-lambda/crons/dailyCleanup.handler',
1487
- schedule: 'rate(1 day)',
1488
- timeout: 300,
1489
- memorySize: 512,
1428
+ export const constructs = {
1429
+ Database: { id: 'Database', kind: 'database' },
1430
+ Api: {
1431
+ id: 'Api',
1432
+ kind: 'rest-api',
1433
+ path: 'apps/api',
1434
+ endpoints: [
1435
+ {
1436
+ id: 'ApiGET/users',
1437
+ method: 'GET',
1438
+ path: '/users',
1439
+ handler: 'apps/api/.gkm/aws/routes/getUsers.handler',
1440
+ dependencies: [{ target: 'Database', kind: 'database' }],
1441
+ authorizer: 'iam',
1442
+ },
1443
+ ],
1444
+ },
1445
+ ProcessData: {
1446
+ id: 'ProcessData',
1447
+ kind: 'function',
1448
+ handler: 'apps/api/.gkm/aws/functions/processData.handler',
1449
+ dependencies: [],
1450
+ },
1451
+ DailyCleanup: {
1452
+ id: 'DailyCleanup',
1453
+ kind: 'cron',
1454
+ handler: 'apps/api/.gkm/aws/crons/dailyCleanup.handler',
1455
+ schedule: 'rate(1 day)',
1456
+ dependencies: [{ target: 'Database', kind: 'database' }],
1457
+ },
1458
+ Emails: {
1459
+ id: 'Emails',
1460
+ kind: 'queue',
1461
+ // The queue's consumer is nested in it
1462
+ worker: {
1463
+ id: 'emails',
1464
+ handler: 'apps/api/.gkm/aws/queues/emails.handler',
1465
+ dependencies: [],
1490
1466
  },
1491
- ],
1492
- subscribers: [],
1493
- } as const;
1467
+ },
1468
+ Users: {
1469
+ id: 'Users',
1470
+ kind: 'topic',
1471
+ events: ['user.created'],
1472
+ // As are a topic's subscribers
1473
+ subscribers: [
1474
+ {
1475
+ id: 'onUser',
1476
+ handler: 'apps/api/.gkm/aws/subscribers/onUser.handler',
1477
+ events: ['user.created'],
1478
+ dependencies: [],
1479
+ },
1480
+ ],
1481
+ },
1482
+ } as const satisfies ConstructManifest;
1483
+
1484
+ export const backends = { cache: 'upstash', email: 'ses' } as const;
1494
1485
 
1495
1486
  // Derived types
1496
- export type Route = (typeof manifest.routes)[number];
1497
- export type Function = (typeof manifest.functions)[number];
1498
- export type Cron = (typeof manifest.crons)[number];
1499
- export type Subscriber = (typeof manifest.subscribers)[number];
1487
+ export type Ids = IdsOf<typeof constructs>;
1488
+ export type Construct<Id extends Ids> = DeclarationOf<typeof constructs, Id>;
1489
+ export type Kind = Construct<Ids>['kind'];
1500
1490
 
1501
1491
  // Useful union types
1502
- export type Authorizer = Route['authorizer'];
1503
- export type HttpMethod = Route['method'];
1504
- export type RoutePath = Route['path'];
1492
+ export type ProvidedKeys = AllProvidedKeys<typeof constructs>;
1493
+ export type Surfaces = IdsOfKind<typeof constructs, 'rest-api'>;
1494
+ export type CacheBackend = (typeof backends)['cache'];
1495
+ export type EmailBackend = (typeof backends)['email'];
1505
1496
  ```
1506
1497
 
1507
- When routes are partitioned, the manifest groups them by partition name and generates partition-aware types:
1498
+ A `RestApi` carries its endpoints, each with its method, path, handler, the
1499
+ dependencies it declared and its authorizer. On AWS the handler is the
1500
+ endpoint's own Lambda (`apps/api/.gkm/aws/routes/<export>.handler`); in the
1501
+ server manifest every endpoint's handler is the app entry
1502
+ (`apps/api/.gkm/server/app.ts`). Functions and crons are top-level
1503
+ declarations; a queue's worker and a topic's subscribers are nested in the
1504
+ queue or topic.
1508
1505
 
1509
- ```typescript
1510
- export const manifest = {
1511
- routes: {
1512
- "admin": [{ path: '/admin/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1513
- "default": [{ path: '/users', method: 'GET', handler: '...', authorizer: 'jwt' }],
1514
- },
1515
- functions: [...], // flat if not partitioned
1516
- } as const;
1506
+ #### Using the Manifest
1517
1507
 
1518
- // Partition-aware derived types
1519
- export type RoutePartition = keyof typeof manifest.routes;
1520
- export type Route<P extends RoutePartition = RoutePartition> =
1521
- (typeof manifest.routes)[P][number];
1522
- ```
1523
-
1524
- #### Server Manifest (`.gkm/manifest/server.ts`)
1508
+ On AWS, `fromManifest` from `@geekmidas/cloud/sst` provisions all of it —
1509
+ resources, each API's endpoints, queue consumers, functions and crons:
1525
1510
 
1526
1511
  ```typescript
1527
- export const manifest = {
1528
- app: {
1529
- handler: '.gkm/server/app.ts',
1530
- endpoints: '.gkm/server/endpoints.ts',
1531
- },
1532
- routes: [
1533
- { path: '/users', method: 'GET', authorizer: 'jwt' },
1534
- { path: '/users', method: 'POST', authorizer: 'jwt' },
1535
- ],
1536
- subscribers: [
1537
- { name: 'orderHandler', subscribedEvents: ['order.created'] },
1538
- ],
1539
- } as const;
1512
+ // sst.config.ts
1513
+ const { App, fromManifest, Stack } = await import('@geekmidas/cloud/sst');
1514
+ const { backends, constructs } = await import('./.gkm/manifest/aws.js');
1540
1515
 
1541
- // Derived types
1542
- export type Route = (typeof manifest.routes)[number];
1543
- export type Subscriber = (typeof manifest.subscribers)[number];
1544
-
1545
- // Useful union types
1546
- export type Authorizer = Route['authorizer'];
1547
- export type HttpMethod = Route['method'];
1548
- export type RoutePath = Route['path'];
1516
+ fromManifest(new Stack(app, 'Shop'), constructs, { Database: { vpc } }, backends);
1549
1517
  ```
1550
1518
 
1551
- #### Using Manifest Types
1552
-
1553
- Import the manifest types for type-safe infrastructure configuration:
1519
+ The types narrow to what was declared:
1554
1520
 
1555
1521
  ```typescript
1556
- import { manifest, type Route, type Authorizer } from './.gkm/manifest/aws';
1522
+ import { constructs, type Construct, type Surfaces } from './.gkm/manifest/aws';
1557
1523
 
1558
- // Type-safe route iteration
1559
- for (const route of manifest.routes) {
1560
- console.log(`${route.method} ${route.path} -> ${route.handler}`);
1561
- }
1524
+ const api: Construct<'Api'> = constructs.Api;
1562
1525
 
1563
- // Use union types for validation
1564
- function isValidMethod(method: string): method is HttpMethod {
1565
- return manifest.routes.some((r) => r.method === method);
1526
+ for (const endpoint of api.endpoints) {
1527
+ console.log(`${endpoint.method} ${endpoint.path} -> ${endpoint.handler}`);
1566
1528
  }
1567
1529
 
1568
- // Access authorizer names
1569
- const authorizers = new Set(manifest.routes.map((r) => r.authorizer));
1530
+ const surface: Surfaces = 'Api'; // any other id is a type error
1570
1531
  ```
1571
1532
 
1572
1533
  ## OpenAPI Generation
@@ -1661,17 +1622,17 @@ provider:
1661
1622
 
1662
1623
  functions:
1663
1624
  getUsers:
1664
- handler: .gkm/aws-apigatewayv1/getUsers.handler
1625
+ handler: .gkm/aws/routes/getUsers.handler
1665
1626
  events:
1666
- - http:
1667
- path: users
1627
+ - httpApi:
1628
+ path: /users
1668
1629
  method: get
1669
-
1630
+
1670
1631
  createUser:
1671
- handler: .gkm/aws-apigatewayv1/createUser.handler
1632
+ handler: .gkm/aws/routes/createUser.handler
1672
1633
  events:
1673
- - http:
1674
- path: users
1634
+ - httpApi:
1635
+ path: /users
1675
1636
  method: post
1676
1637
  ```
1677
1638
 
@@ -1922,7 +1883,7 @@ Error: OpenAPI generation failed: Invalid endpoint schema
1922
1883
  "dev": "gkm dev",
1923
1884
  "dev:port": "gkm dev --port 8080",
1924
1885
  "build": "gkm build",
1925
- "build:lambda": "gkm build --provider aws-apigatewayv1",
1886
+ "build:lambda": "gkm build --provider aws",
1926
1887
  "build:server": "gkm build --provider server",
1927
1888
  "docs": "gkm openapi --output src/api.ts"
1928
1889
  }
@@ -2016,8 +1977,8 @@ DEBUG=gkm:* npx gkm build
2016
1977
  ### Types
2017
1978
 
2018
1979
  ```typescript
2019
- // Provider options
2020
- type Provider = 'server' | 'aws-apigatewayv1' | 'aws-apigatewayv2';
1980
+ // Build targets
1981
+ type Provider = 'aws' | 'server';
2021
1982
 
2022
1983
  // Runtime options
2023
1984
  type Runtime = 'node' | 'bun';
@@ -2055,7 +2016,7 @@ interface TelescopeConfig {
2055
2016
 
2056
2017
  // Build options
2057
2018
  interface BuildOptions {
2058
- provider: Provider;
2019
+ provider?: Provider; // default: where gkm.config.ts deploys
2059
2020
  }
2060
2021
 
2061
2022
  // Dev options
@@ -1,4 +1,4 @@
1
- const require_discover = require("./discover-B0f_kuNN.cjs");
1
+ const require_discover = require("./discover-DXNviAh-.cjs");
2
2
  let node_fs_promises = require("node:fs/promises");
3
3
  let node_path = require("node:path");
4
4
  let _geekmidas_constructs_endpoints = require("@geekmidas/constructs/endpoints");
@@ -667,45 +667,32 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
667
667
  return _geekmidas_constructs_endpoints.Endpoint.isEndpoint(value);
668
668
  }
669
669
  async build(context, constructs, outputDir, options) {
670
- const provider = options?.provider || "aws-apigatewayv2";
670
+ const target = options?.target ?? "aws";
671
+ const root = options?.root ?? process.cwd();
671
672
  const enableOpenApi = options?.enableOpenApi || false;
672
673
  const logger = console;
673
674
  const routes = [];
674
675
  if (constructs.length === 0) return routes;
675
- if (provider === "server") {
676
+ if (target === "server") {
676
677
  await this.generateEndpointsFile(outputDir, constructs, context);
677
678
  const appFile = await this.generateAppFile(outputDir, context);
678
679
  routes.push({
679
680
  path: "*",
680
681
  method: "ALL",
681
- handler: (0, node_path.relative)(process.cwd(), appFile),
682
+ handler: (0, node_path.relative)(root, appFile),
682
683
  authorizer: "none"
683
684
  });
684
685
  logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
685
- } else if (provider === "aws-lambda") {
686
- const routesDir = (0, node_path.join)(outputDir, "routes");
687
- await (0, node_fs_promises.mkdir)(routesDir, { recursive: true });
688
- for (const { key, construct, path } of constructs) {
689
- const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, "aws-apigatewayv2", construct, context);
690
- const routeInfo = {
691
- path: construct._path,
692
- method: construct.method,
693
- handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
694
- timeout: construct.timeout,
695
- memorySize: construct.memorySize,
696
- environment: await construct.getEnvironment({ markOptional: context.markOptional }),
697
- dependencies: construct.constructs,
698
- authorizer: construct.authorizer?.name ?? "none"
699
- };
700
- routes.push(routeInfo);
701
- logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
702
- }
703
- } else for (const { key, construct, path } of constructs) {
704
- const handlerFile = await this.generateHandlerFile(outputDir, path.relative, key, provider, construct, context);
686
+ return routes;
687
+ }
688
+ const routesDir = (0, node_path.join)(outputDir, "routes");
689
+ await (0, node_fs_promises.mkdir)(routesDir, { recursive: true });
690
+ for (const { key, construct, path } of constructs) {
691
+ const handlerFile = await this.generateHandlerFile(routesDir, path.relative, key, context);
705
692
  const routeInfo = {
706
693
  path: construct._path,
707
694
  method: construct.method,
708
- handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
695
+ handler: (0, node_path.relative)(root, handlerFile).replace(/\.ts$/, ".handler"),
709
696
  timeout: construct.timeout,
710
697
  memorySize: construct.memorySize,
711
698
  environment: await construct.getEnvironment({ markOptional: context.markOptional }),
@@ -717,24 +704,10 @@ var EndpointGenerator = class extends require_discover.ConstructGenerator {
717
704
  }
718
705
  return routes;
719
706
  }
720
- async generateHandlerFile(outputDir, sourceFile, exportName, provider, _endpoint, context) {
721
- const handlerFileName = `${exportName}.ts`;
722
- const handlerPath = (0, node_path.join)(outputDir, handlerFileName);
707
+ async generateHandlerFile(outputDir, sourceFile, exportName, context) {
708
+ const handlerPath = (0, node_path.join)(outputDir, `${exportName}.ts`);
723
709
  const importPath = (0, node_path.relative)((0, node_path.dirname)(handlerPath), sourceFile).replace(/\.ts$/, ".js");
724
- let content;
725
- switch (provider) {
726
- case "aws-apigatewayv1":
727
- content = this.generateAWSApiGatewayV1Handler(importPath, exportName, context.storageDrivers);
728
- break;
729
- case "aws-apigatewayv2":
730
- content = this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers);
731
- break;
732
- case "server":
733
- content = this.generateServerHandler(importPath, exportName);
734
- break;
735
- default: throw new Error(`Unsupported provider: ${provider}`);
736
- }
737
- await (0, node_fs_promises.writeFile)(handlerPath, content);
710
+ await (0, node_fs_promises.writeFile)(handlerPath, this.generateAWSApiGatewayV2Handler(importPath, exportName, context.storageDrivers));
738
711
  return handlerPath;
739
712
  }
740
713
  async generateEndpointsFile(outputDir, endpoints, context) {
@@ -1111,26 +1084,6 @@ export default createApp;
1111
1084
  * object. Nothing has to be printed now, which is also why nothing has to be
1112
1085
  * named in config.
1113
1086
  */
1114
- generateAWSApiGatewayV1Handler(importPath, exportName, drivers) {
1115
- return `import { AmazonApiGatewayV1Endpoint } from '@geekmidas/constructs/aws';
1116
- import { ${exportName} } from '${importPath}';
1117
- ${drivers?.imports ?? ""}
1118
- ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${drivers.setup}\n` : ""}
1119
- const adapter = new AmazonApiGatewayV1Endpoint(${exportName});
1120
-
1121
- export const handler = adapter.handler;
1122
- `;
1123
- }
1124
- /**
1125
- * One Lambda, one endpoint — and no environment import.
1126
- *
1127
- * The endpoint was built from its surface, so it carries the parser the
1128
- * adaptor needs. This used to read
1129
- * `import { envParser } from '../../config/env'`, a line the build wrote
1130
- * because a generator can print a module specifier and cannot print an
1131
- * object. Nothing has to be printed now, which is also why nothing has to be
1132
- * named in config.
1133
- */
1134
1087
  generateAWSApiGatewayV2Handler(importPath, exportName, drivers) {
1135
1088
  return `import { AmazonApiGatewayV2Endpoint } from '@geekmidas/constructs/aws';
1136
1089
  import { ${exportName} } from '${importPath}';
@@ -1139,13 +1092,6 @@ ${drivers?.setup ? `\n// The handler registers the drivers its target needs.\n${
1139
1092
  const adapter = new AmazonApiGatewayV2Endpoint(${exportName});
1140
1093
 
1141
1094
  export const handler = adapter.handler;
1142
- `;
1143
- }
1144
- generateServerHandler(importPath, exportName) {
1145
- return `import { ${exportName} } from '${importPath}';
1146
-
1147
- // Server handler - implement based on your server framework
1148
- export const handler = ${exportName};
1149
1095
  `;
1150
1096
  }
1151
1097
  /**
@@ -1298,7 +1244,7 @@ export default createApp;
1298
1244
  await (0, node_fs_promises.writeFile)(serverPath, `#!/usr/bin/env node
1299
1245
  /**
1300
1246
  * Production server entry point
1301
- * Generated by 'gkm build --provider server --production'
1247
+ * Generated by 'gkm build --production'
1302
1248
  */
1303
1249
  import { serve } from '@hono/node-server';
1304
1250
  import { createApp } from './app.js';
@@ -1839,4 +1785,4 @@ Object.defineProperty(exports, "runtimeFor", {
1839
1785
  }
1840
1786
  });
1841
1787
 
1842
- //# sourceMappingURL=OpenApiTsGenerator-B4Kj_qNU.cjs.map
1788
+ //# sourceMappingURL=OpenApiTsGenerator-BN0PIZxd.cjs.map