@geekmidas/cli 10.0.0-alpha.45 → 10.0.0-alpha.47
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/README.md +144 -183
- package/dist/{OpenApiTsGenerator-B4Kj_qNU.cjs → OpenApiTsGenerator-BN0PIZxd.cjs} +17 -71
- package/dist/OpenApiTsGenerator-BN0PIZxd.cjs.map +1 -0
- package/dist/{OpenApiTsGenerator-CEh3EKN3.mjs → OpenApiTsGenerator-BzIGy8KE.mjs} +17 -71
- package/dist/OpenApiTsGenerator-BzIGy8KE.mjs.map +1 -0
- package/dist/backends-B9V2XD2M.cjs +82 -0
- package/dist/backends-B9V2XD2M.cjs.map +1 -0
- package/dist/backends-CSuLl0YP.mjs +59 -0
- package/dist/backends-CSuLl0YP.mjs.map +1 -0
- package/dist/{config-CJ-PAb7M.cjs → config-CsYSyUya.cjs} +3 -3
- package/dist/{config-CJ-PAb7M.cjs.map → config-CsYSyUya.cjs.map} +1 -1
- package/dist/{config-5watB1D0.mjs → config-D8J5rrTb.mjs} +3 -3
- package/dist/{config-5watB1D0.mjs.map → config-D8J5rrTb.mjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +2 -2
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +2 -2
- package/dist/{discover-BLhf7V_J.mjs → discover-Cf2jAcgF.mjs} +4 -56
- package/dist/discover-Cf2jAcgF.mjs.map +1 -0
- package/dist/{discover-B0f_kuNN.cjs → discover-DXNviAh-.cjs} +3 -79
- package/dist/discover-DXNviAh-.cjs.map +1 -0
- package/dist/{emit-Bzq7JsMP.mjs → emit-C1e8qD08.mjs} +12 -43
- package/dist/emit-C1e8qD08.mjs.map +1 -0
- package/dist/{emit-BdoPFjZf.cjs → emit-Dmc1nvdS.cjs} +11 -54
- package/dist/emit-Dmc1nvdS.cjs.map +1 -0
- package/dist/encryption-C7OGMve_.cjs +91 -0
- package/dist/encryption-C7OGMve_.cjs.map +1 -0
- package/dist/encryption-DyQnPsZN.mjs +90 -0
- package/dist/encryption-DyQnPsZN.mjs.map +1 -0
- package/dist/{github-D5MthUlR.mjs → github-BfpadQWQ.mjs} +3 -3
- package/dist/{github-D5MthUlR.mjs.map → github-BfpadQWQ.mjs.map} +1 -1
- package/dist/{github-BAr8WGkR.cjs → github-BrI1tv6u.cjs} +3 -3
- package/dist/{github-BAr8WGkR.cjs.map → github-BrI1tv6u.cjs.map} +1 -1
- package/dist/{index-B3PeGOQp.d.cts → index-BQhJXpaQ.d.mts} +2 -2
- package/dist/{index-B3PeGOQp.d.cts.map → index-BQhJXpaQ.d.mts.map} +1 -1
- package/dist/{index-BOyaGcCm.d.mts → index-DHJePE0y.d.cts} +2 -2
- package/dist/{index-BOyaGcCm.d.mts.map → index-DHJePE0y.d.cts.map} +1 -1
- package/dist/index.cjs +444 -670
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +442 -668
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-PJi4b1ga.cjs → migrate-BgEY9pdP.cjs} +5 -5
- package/dist/{migrate-PJi4b1ga.cjs.map → migrate-BgEY9pdP.cjs.map} +1 -1
- package/dist/{migrate-BRklCm7b.mjs → migrate-DhxTIA0z.mjs} +5 -5
- package/dist/{migrate-BRklCm7b.mjs.map → migrate-DhxTIA0z.mjs.map} +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/{ready-ZqOuNvKD.mjs → ready-WfT-eWlm.mjs} +50 -8
- package/dist/ready-WfT-eWlm.mjs.map +1 -0
- package/dist/{ready-3RfHxdA0.cjs → ready-lr2Fm-ep.cjs} +68 -8
- package/dist/ready-lr2Fm-ep.cjs.map +1 -0
- package/dist/reconcile/public.cjs +2 -4
- package/dist/reconcile/public.d.cts +6 -10
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +6 -10
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -3
- package/dist/{types-0R124hrY.d.mts → types-BbrNu83u.d.mts} +14 -109
- package/dist/{types-0R124hrY.d.mts.map → types-BbrNu83u.d.mts.map} +1 -1
- package/dist/{types-DfdYe31u.d.cts → types-DNqEsctD.d.cts} +14 -109
- package/dist/{types-DfdYe31u.d.cts.map → types-DNqEsctD.d.cts.map} +1 -1
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-RYSYtHP7.cjs → workspace-DEibcoBe.cjs} +11 -25
- package/dist/{workspace-RYSYtHP7.cjs.map → workspace-DEibcoBe.cjs.map} +1 -1
- package/dist/{workspace-DOmIhiau.mjs → workspace-DNzWgM1J.mjs} +11 -25
- package/dist/{workspace-DOmIhiau.mjs.map → workspace-DNzWgM1J.mjs.map} +1 -1
- package/dist/{workspace-BKytVCzb.mjs → workspace-cb6U29EL.mjs} +59 -81
- package/dist/workspace-cb6U29EL.mjs.map +1 -0
- package/dist/{workspace-dV6f-3vv.cjs → workspace-vafrzZTC.cjs} +65 -105
- package/dist/workspace-vafrzZTC.cjs.map +1 -0
- package/package.json +14 -14
- package/dist/OpenApiTsGenerator-B4Kj_qNU.cjs.map +0 -1
- package/dist/OpenApiTsGenerator-CEh3EKN3.mjs.map +0 -1
- package/dist/discover-B0f_kuNN.cjs.map +0 -1
- package/dist/discover-BLhf7V_J.mjs.map +0 -1
- package/dist/emit-BdoPFjZf.cjs.map +0 -1
- package/dist/emit-Bzq7JsMP.mjs.map +0 -1
- package/dist/ready-3RfHxdA0.cjs.map +0 -1
- package/dist/ready-ZqOuNvKD.mjs.map +0 -1
- package/dist/workspace-BKytVCzb.mjs.map +0 -1
- 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
|
-
#
|
|
190
|
-
npx gkm build
|
|
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>`:
|
|
316
|
-
- `aws
|
|
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
|
-
#
|
|
324
|
-
gkm build
|
|
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.
|
|
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.
|
|
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
|
|
1049
|
-
type Routes = string | string[]
|
|
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
|
|
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
|
|
1061
|
-
crons?: Routes; // Glob patterns
|
|
1062
|
-
subscribers?: Routes; // Glob patterns
|
|
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
|
|
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
|
-
##
|
|
1337
|
+
## Build Targets
|
|
1361
1338
|
|
|
1362
|
-
### AWS
|
|
1339
|
+
### AWS
|
|
1363
1340
|
|
|
1364
|
-
Generates Lambda
|
|
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
|
|
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 '
|
|
1393
|
-
import { envParser } from '../src/env.js';
|
|
1352
|
+
import { myEndpoint } from '../../../src/routes/example.js';
|
|
1394
1353
|
|
|
1395
|
-
const adapter = new AmazonApiGatewayV2Endpoint(
|
|
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
|
-
|
|
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
|
-
|
|
1441
|
-
├──
|
|
1442
|
-
│ ├──
|
|
1443
|
-
│
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
│ ├──
|
|
1447
|
-
├──
|
|
1448
|
-
│ ├──
|
|
1449
|
-
│
|
|
1450
|
-
└──
|
|
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
|
|
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
|
-
|
|
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
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
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
|
-
|
|
1493
|
-
|
|
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
|
|
1497
|
-
export type
|
|
1498
|
-
export type
|
|
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
|
|
1503
|
-
export type
|
|
1504
|
-
export type
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1519
|
-
|
|
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
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
1522
|
+
import { constructs, type Construct, type Surfaces } from './.gkm/manifest/aws';
|
|
1557
1523
|
|
|
1558
|
-
|
|
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
|
-
|
|
1564
|
-
|
|
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
|
-
//
|
|
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
|
|
1625
|
+
handler: .gkm/aws/routes/getUsers.handler
|
|
1665
1626
|
events:
|
|
1666
|
-
-
|
|
1667
|
-
path: users
|
|
1627
|
+
- httpApi:
|
|
1628
|
+
path: /users
|
|
1668
1629
|
method: get
|
|
1669
|
-
|
|
1630
|
+
|
|
1670
1631
|
createUser:
|
|
1671
|
-
handler: .gkm/aws
|
|
1632
|
+
handler: .gkm/aws/routes/createUser.handler
|
|
1672
1633
|
events:
|
|
1673
|
-
-
|
|
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
|
|
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
|
-
//
|
|
2020
|
-
type Provider = '
|
|
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
|
|
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-
|
|
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
|
|
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 (
|
|
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)(
|
|
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
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
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)(
|
|
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,
|
|
721
|
-
const
|
|
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
|
-
|
|
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 --
|
|
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-
|
|
1788
|
+
//# sourceMappingURL=OpenApiTsGenerator-BN0PIZxd.cjs.map
|