@geekmidas/cli 0.25.0 → 0.27.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/{config-CTftATBX.cjs → config-BhryDQEq.cjs} +2 -2
- package/dist/{config-CTftATBX.cjs.map → config-BhryDQEq.cjs.map} +1 -1
- package/dist/{config-BogU0_oQ.mjs → config-C9bdq0l-.mjs} +2 -2
- package/dist/{config-BogU0_oQ.mjs.map → config-C9bdq0l-.mjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.mjs +2 -2
- package/dist/index-CWN-bgrO.d.mts.map +1 -1
- package/dist/index-DEWYvYvg.d.cts.map +1 -1
- package/dist/index.cjs +128 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +128 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-DNbXfhXE.mjs → openapi-BCEFhkLh.mjs} +2 -2
- package/dist/{openapi-DNbXfhXE.mjs.map → openapi-BCEFhkLh.mjs.map} +1 -1
- package/dist/{openapi-BrhkPKM7.cjs → openapi-D82bBqG7.cjs} +2 -2
- package/dist/{openapi-BrhkPKM7.cjs.map → openapi-D82bBqG7.cjs.map} +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.mjs +3 -3
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-iWgBlX6h.cjs → workspace-CiZBOjf9.cjs} +1 -7
- package/dist/{workspace-iWgBlX6h.cjs.map → workspace-CiZBOjf9.cjs.map} +1 -1
- package/dist/{workspace-CPLEZDZf.mjs → workspace-DQjmv9lk.mjs} +1 -7
- package/dist/{workspace-CPLEZDZf.mjs.map → workspace-DQjmv9lk.mjs.map} +1 -1
- package/package.json +4 -4
- package/src/init/__tests__/generators.spec.ts +12 -6
- package/src/init/__tests__/init.spec.ts +18 -6
- package/src/init/generators/models.ts +49 -19
- package/src/init/templates/api.ts +57 -3
- package/src/init/templates/minimal.ts +8 -0
- package/src/init/templates/serverless.ts +9 -0
- package/src/init/templates/worker.ts +9 -1
- package/src/init/versions.ts +1 -1
- package/src/workspace/__tests__/index.spec.ts +5 -6
- package/src/workspace/__tests__/schema.spec.ts +5 -5
- package/src/workspace/schema.ts +1 -13
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env -S npx tsx
|
|
2
|
-
import { __require, getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-
|
|
3
|
-
import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-
|
|
4
|
-
import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, OpenApiTsGenerator, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-
|
|
2
|
+
import { __require, getAppBuildOrder, getDependencyEnvVars, getDeployTargetError, isDeployTargetSupported } from "./workspace-DQjmv9lk.mjs";
|
|
3
|
+
import { getAppNameFromCwd, loadAppConfig, loadConfig, loadWorkspaceConfig, parseModuleConfig } from "./config-C9bdq0l-.mjs";
|
|
4
|
+
import { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, OpenApiTsGenerator, generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi-BCEFhkLh.mjs";
|
|
5
5
|
import { getKeyPath, maskPassword, readStageSecrets, secretsExist, setCustomSecret, toEmbeddableSecrets, writeStageSecrets } from "./storage-Dhst7BhI.mjs";
|
|
6
6
|
import { DokployApi } from "./dokploy-api-B9qR2Yn1.mjs";
|
|
7
7
|
import { generateReactQueryCommand } from "./openapi-react-query-5rSortLH.mjs";
|
|
@@ -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.
|
|
29
|
+
var version = "0.27.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";
|
|
@@ -4292,7 +4292,7 @@ const GEEKMIDAS_VERSIONS = {
|
|
|
4292
4292
|
"@geekmidas/services": "~0.2.0",
|
|
4293
4293
|
"@geekmidas/storage": "~0.1.0",
|
|
4294
4294
|
"@geekmidas/studio": "~0.4.0",
|
|
4295
|
-
"@geekmidas/telescope": "~0.
|
|
4295
|
+
"@geekmidas/telescope": "~0.5.0",
|
|
4296
4296
|
"@geekmidas/testkit": "~0.6.0"
|
|
4297
4297
|
};
|
|
4298
4298
|
|
|
@@ -4974,25 +4974,25 @@ function generateModelsPackage(options) {
|
|
|
4974
4974
|
include: ["src/**/*.ts"],
|
|
4975
4975
|
exclude: ["node_modules", "dist"]
|
|
4976
4976
|
};
|
|
4977
|
-
const
|
|
4977
|
+
const commonTs = `import { z } from 'zod';
|
|
4978
4978
|
|
|
4979
4979
|
// ============================================
|
|
4980
4980
|
// Common Schemas
|
|
4981
4981
|
// ============================================
|
|
4982
4982
|
|
|
4983
|
-
export const
|
|
4983
|
+
export const IdSchema = z.string().uuid();
|
|
4984
4984
|
|
|
4985
|
-
export const
|
|
4985
|
+
export const TimestampsSchema = z.object({
|
|
4986
4986
|
createdAt: z.coerce.date(),
|
|
4987
4987
|
updatedAt: z.coerce.date(),
|
|
4988
4988
|
});
|
|
4989
4989
|
|
|
4990
|
-
export const
|
|
4990
|
+
export const PaginationSchema = z.object({
|
|
4991
4991
|
page: z.coerce.number().int().positive().default(1),
|
|
4992
4992
|
limit: z.coerce.number().int().positive().max(100).default(20),
|
|
4993
4993
|
});
|
|
4994
4994
|
|
|
4995
|
-
export const
|
|
4995
|
+
export const PaginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =>
|
|
4996
4996
|
z.object({
|
|
4997
4997
|
items: z.array(itemSchema),
|
|
4998
4998
|
total: z.number(),
|
|
@@ -5001,35 +5001,59 @@ export const paginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =
|
|
|
5001
5001
|
totalPages: z.number(),
|
|
5002
5002
|
});
|
|
5003
5003
|
|
|
5004
|
+
// ============================================
|
|
5005
|
+
// Type Exports
|
|
5006
|
+
// ============================================
|
|
5007
|
+
|
|
5008
|
+
export type Id = z.infer<typeof IdSchema>;
|
|
5009
|
+
export type Timestamps = z.infer<typeof TimestampsSchema>;
|
|
5010
|
+
export type Pagination = z.infer<typeof PaginationSchema>;
|
|
5011
|
+
`;
|
|
5012
|
+
const userTs = `import { z } from 'zod';
|
|
5013
|
+
import { IdSchema, TimestampsSchema } from './common.js';
|
|
5014
|
+
|
|
5004
5015
|
// ============================================
|
|
5005
5016
|
// User Schemas
|
|
5006
5017
|
// ============================================
|
|
5007
5018
|
|
|
5008
|
-
export const
|
|
5009
|
-
id:
|
|
5019
|
+
export const UserSchema = z.object({
|
|
5020
|
+
id: IdSchema,
|
|
5010
5021
|
email: z.string().email(),
|
|
5011
5022
|
name: z.string().min(1).max(100),
|
|
5012
|
-
...
|
|
5023
|
+
...TimestampsSchema.shape,
|
|
5013
5024
|
});
|
|
5014
5025
|
|
|
5015
|
-
export const
|
|
5026
|
+
export const CreateUserSchema = UserSchema.omit({
|
|
5016
5027
|
id: true,
|
|
5017
5028
|
createdAt: true,
|
|
5018
5029
|
updatedAt: true,
|
|
5019
5030
|
});
|
|
5020
5031
|
|
|
5021
|
-
export const
|
|
5032
|
+
export const UpdateUserSchema = CreateUserSchema.partial();
|
|
5033
|
+
|
|
5034
|
+
// ============================================
|
|
5035
|
+
// Response Schemas
|
|
5036
|
+
// ============================================
|
|
5037
|
+
|
|
5038
|
+
export const UserResponseSchema = UserSchema.pick({
|
|
5039
|
+
id: true,
|
|
5040
|
+
name: true,
|
|
5041
|
+
email: true,
|
|
5042
|
+
});
|
|
5043
|
+
|
|
5044
|
+
export const ListUsersResponseSchema = z.object({
|
|
5045
|
+
users: z.array(UserSchema.pick({ id: true, name: true })),
|
|
5046
|
+
});
|
|
5022
5047
|
|
|
5023
5048
|
// ============================================
|
|
5024
5049
|
// Type Exports
|
|
5025
5050
|
// ============================================
|
|
5026
5051
|
|
|
5027
|
-
export type
|
|
5028
|
-
export type
|
|
5029
|
-
export type
|
|
5030
|
-
export type
|
|
5031
|
-
export type
|
|
5032
|
-
export type UpdateUser = z.infer<typeof updateUserSchema>;
|
|
5052
|
+
export type User = z.infer<typeof UserSchema>;
|
|
5053
|
+
export type CreateUser = z.infer<typeof CreateUserSchema>;
|
|
5054
|
+
export type UpdateUser = z.infer<typeof UpdateUserSchema>;
|
|
5055
|
+
export type UserResponse = z.infer<typeof UserResponseSchema>;
|
|
5056
|
+
export type ListUsersResponse = z.infer<typeof ListUsersResponseSchema>;
|
|
5033
5057
|
`;
|
|
5034
5058
|
return [
|
|
5035
5059
|
{
|
|
@@ -5041,8 +5065,12 @@ export type UpdateUser = z.infer<typeof updateUserSchema>;
|
|
|
5041
5065
|
content: `${JSON.stringify(tsConfig, null, 2)}\n`
|
|
5042
5066
|
},
|
|
5043
5067
|
{
|
|
5044
|
-
path: "packages/models/src/
|
|
5045
|
-
content:
|
|
5068
|
+
path: "packages/models/src/common.ts",
|
|
5069
|
+
content: commonTs
|
|
5070
|
+
},
|
|
5071
|
+
{
|
|
5072
|
+
path: "packages/models/src/user.ts",
|
|
5073
|
+
content: userTs
|
|
5046
5074
|
}
|
|
5047
5075
|
];
|
|
5048
5076
|
}
|
|
@@ -5342,10 +5370,13 @@ const apiTemplate = {
|
|
|
5342
5370
|
name: "api",
|
|
5343
5371
|
description: "Full API with auth, database, services",
|
|
5344
5372
|
dependencies: {
|
|
5373
|
+
"@geekmidas/audit": GEEKMIDAS_VERSIONS["@geekmidas/audit"],
|
|
5345
5374
|
"@geekmidas/constructs": GEEKMIDAS_VERSIONS["@geekmidas/constructs"],
|
|
5346
5375
|
"@geekmidas/envkit": GEEKMIDAS_VERSIONS["@geekmidas/envkit"],
|
|
5347
5376
|
"@geekmidas/events": GEEKMIDAS_VERSIONS["@geekmidas/events"],
|
|
5348
5377
|
"@geekmidas/logger": GEEKMIDAS_VERSIONS["@geekmidas/logger"],
|
|
5378
|
+
"@geekmidas/rate-limit": GEEKMIDAS_VERSIONS["@geekmidas/rate-limit"],
|
|
5379
|
+
"@geekmidas/schema": GEEKMIDAS_VERSIONS["@geekmidas/schema"],
|
|
5349
5380
|
"@geekmidas/services": GEEKMIDAS_VERSIONS["@geekmidas/services"],
|
|
5350
5381
|
"@geekmidas/errors": GEEKMIDAS_VERSIONS["@geekmidas/errors"],
|
|
5351
5382
|
"@geekmidas/auth": GEEKMIDAS_VERSIONS["@geekmidas/auth"],
|
|
@@ -5373,11 +5404,12 @@ const apiTemplate = {
|
|
|
5373
5404
|
"fmt:check": "biome format ."
|
|
5374
5405
|
},
|
|
5375
5406
|
files: (options) => {
|
|
5376
|
-
const { loggerType, routesStructure } = options;
|
|
5407
|
+
const { loggerType, routesStructure, monorepo, name: name$1 } = options;
|
|
5377
5408
|
const loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';
|
|
5378
5409
|
|
|
5379
5410
|
export const logger = createLogger();
|
|
5380
5411
|
`;
|
|
5412
|
+
const modelsImport = monorepo ? `@${name$1}/models` : null;
|
|
5381
5413
|
const getRoutePath = (file) => {
|
|
5382
5414
|
switch (routesStructure) {
|
|
5383
5415
|
case "centralized-endpoints": return `src/endpoints/${file}`;
|
|
@@ -5414,9 +5446,14 @@ export const config = envParser
|
|
|
5414
5446
|
{
|
|
5415
5447
|
path: getRoutePath("health.ts"),
|
|
5416
5448
|
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5449
|
+
import { z } from 'zod';
|
|
5417
5450
|
|
|
5418
5451
|
export const healthEndpoint = e
|
|
5419
5452
|
.get('/health')
|
|
5453
|
+
.output(z.object({
|
|
5454
|
+
status: z.string(),
|
|
5455
|
+
timestamp: z.string(),
|
|
5456
|
+
}))
|
|
5420
5457
|
.handle(async () => ({
|
|
5421
5458
|
status: 'ok',
|
|
5422
5459
|
timestamp: new Date().toISOString(),
|
|
@@ -5425,10 +5462,31 @@ export const healthEndpoint = e
|
|
|
5425
5462
|
},
|
|
5426
5463
|
{
|
|
5427
5464
|
path: getRoutePath("users/list.ts"),
|
|
5428
|
-
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5465
|
+
content: modelsImport ? `import { e } from '@geekmidas/constructs/endpoints';
|
|
5466
|
+
import { ListUsersResponseSchema } from '${modelsImport}/user';
|
|
5467
|
+
|
|
5468
|
+
export const listUsersEndpoint = e
|
|
5469
|
+
.get('/users')
|
|
5470
|
+
.output(ListUsersResponseSchema)
|
|
5471
|
+
.handle(async () => ({
|
|
5472
|
+
users: [
|
|
5473
|
+
{ id: '1', name: 'Alice' },
|
|
5474
|
+
{ id: '2', name: 'Bob' },
|
|
5475
|
+
],
|
|
5476
|
+
}));
|
|
5477
|
+
` : `import { e } from '@geekmidas/constructs/endpoints';
|
|
5478
|
+
import { z } from 'zod';
|
|
5479
|
+
|
|
5480
|
+
const UserSchema = z.object({
|
|
5481
|
+
id: z.string(),
|
|
5482
|
+
name: z.string(),
|
|
5483
|
+
});
|
|
5429
5484
|
|
|
5430
5485
|
export const listUsersEndpoint = e
|
|
5431
5486
|
.get('/users')
|
|
5487
|
+
.output(z.object({
|
|
5488
|
+
users: z.array(UserSchema),
|
|
5489
|
+
}))
|
|
5432
5490
|
.handle(async () => ({
|
|
5433
5491
|
users: [
|
|
5434
5492
|
{ id: '1', name: 'Alice' },
|
|
@@ -5439,12 +5497,30 @@ export const listUsersEndpoint = e
|
|
|
5439
5497
|
},
|
|
5440
5498
|
{
|
|
5441
5499
|
path: getRoutePath("users/get.ts"),
|
|
5442
|
-
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5500
|
+
content: modelsImport ? `import { e } from '@geekmidas/constructs/endpoints';
|
|
5443
5501
|
import { z } from 'zod';
|
|
5502
|
+
import { UserResponseSchema } from '${modelsImport}/user';
|
|
5444
5503
|
|
|
5445
5504
|
export const getUserEndpoint = e
|
|
5446
5505
|
.get('/users/:id')
|
|
5447
5506
|
.params(z.object({ id: z.string() }))
|
|
5507
|
+
.output(UserResponseSchema)
|
|
5508
|
+
.handle(async ({ params }) => ({
|
|
5509
|
+
id: params.id,
|
|
5510
|
+
name: 'Alice',
|
|
5511
|
+
email: 'alice@example.com',
|
|
5512
|
+
}));
|
|
5513
|
+
` : `import { e } from '@geekmidas/constructs/endpoints';
|
|
5514
|
+
import { z } from 'zod';
|
|
5515
|
+
|
|
5516
|
+
export const getUserEndpoint = e
|
|
5517
|
+
.get('/users/:id')
|
|
5518
|
+
.params(z.object({ id: z.string() }))
|
|
5519
|
+
.output(z.object({
|
|
5520
|
+
id: z.string(),
|
|
5521
|
+
name: z.string(),
|
|
5522
|
+
email: z.string().email(),
|
|
5523
|
+
}))
|
|
5448
5524
|
.handle(async ({ params }) => ({
|
|
5449
5525
|
id: params.id,
|
|
5450
5526
|
name: 'Alice',
|
|
@@ -5548,9 +5624,12 @@ const minimalTemplate = {
|
|
|
5548
5624
|
name: "minimal",
|
|
5549
5625
|
description: "Basic health endpoint",
|
|
5550
5626
|
dependencies: {
|
|
5627
|
+
"@geekmidas/audit": GEEKMIDAS_VERSIONS["@geekmidas/audit"],
|
|
5551
5628
|
"@geekmidas/constructs": GEEKMIDAS_VERSIONS["@geekmidas/constructs"],
|
|
5552
5629
|
"@geekmidas/envkit": GEEKMIDAS_VERSIONS["@geekmidas/envkit"],
|
|
5553
5630
|
"@geekmidas/logger": GEEKMIDAS_VERSIONS["@geekmidas/logger"],
|
|
5631
|
+
"@geekmidas/rate-limit": GEEKMIDAS_VERSIONS["@geekmidas/rate-limit"],
|
|
5632
|
+
"@geekmidas/schema": GEEKMIDAS_VERSIONS["@geekmidas/schema"],
|
|
5554
5633
|
"@hono/node-server": "~1.14.1",
|
|
5555
5634
|
hono: "~4.8.2",
|
|
5556
5635
|
pino: "~9.6.0"
|
|
@@ -5612,9 +5691,14 @@ export const config = envParser
|
|
|
5612
5691
|
{
|
|
5613
5692
|
path: getRoutePath("health.ts"),
|
|
5614
5693
|
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5694
|
+
import { z } from 'zod';
|
|
5615
5695
|
|
|
5616
5696
|
export const healthEndpoint = e
|
|
5617
5697
|
.get('/health')
|
|
5698
|
+
.output(z.object({
|
|
5699
|
+
status: z.string(),
|
|
5700
|
+
timestamp: z.string(),
|
|
5701
|
+
}))
|
|
5618
5702
|
.handle(async () => ({
|
|
5619
5703
|
status: 'ok',
|
|
5620
5704
|
timestamp: new Date().toISOString(),
|
|
@@ -5712,10 +5796,13 @@ const serverlessTemplate = {
|
|
|
5712
5796
|
name: "serverless",
|
|
5713
5797
|
description: "AWS Lambda handlers",
|
|
5714
5798
|
dependencies: {
|
|
5799
|
+
"@geekmidas/audit": GEEKMIDAS_VERSIONS["@geekmidas/audit"],
|
|
5715
5800
|
"@geekmidas/constructs": GEEKMIDAS_VERSIONS["@geekmidas/constructs"],
|
|
5716
5801
|
"@geekmidas/envkit": GEEKMIDAS_VERSIONS["@geekmidas/envkit"],
|
|
5717
5802
|
"@geekmidas/logger": GEEKMIDAS_VERSIONS["@geekmidas/logger"],
|
|
5718
5803
|
"@geekmidas/cloud": GEEKMIDAS_VERSIONS["@geekmidas/cloud"],
|
|
5804
|
+
"@geekmidas/rate-limit": GEEKMIDAS_VERSIONS["@geekmidas/rate-limit"],
|
|
5805
|
+
"@geekmidas/schema": GEEKMIDAS_VERSIONS["@geekmidas/schema"],
|
|
5719
5806
|
"@hono/node-server": "~1.14.1",
|
|
5720
5807
|
hono: "~4.8.2",
|
|
5721
5808
|
pino: "~9.6.0"
|
|
@@ -5778,9 +5865,15 @@ export const config = envParser
|
|
|
5778
5865
|
{
|
|
5779
5866
|
path: getRoutePath("health.ts"),
|
|
5780
5867
|
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5868
|
+
import { z } from 'zod';
|
|
5781
5869
|
|
|
5782
5870
|
export const healthEndpoint = e
|
|
5783
5871
|
.get('/health')
|
|
5872
|
+
.output(z.object({
|
|
5873
|
+
status: z.string(),
|
|
5874
|
+
timestamp: z.string(),
|
|
5875
|
+
region: z.string(),
|
|
5876
|
+
}))
|
|
5784
5877
|
.handle(async () => ({
|
|
5785
5878
|
status: 'ok',
|
|
5786
5879
|
timestamp: new Date().toISOString(),
|
|
@@ -5824,10 +5917,13 @@ const workerTemplate = {
|
|
|
5824
5917
|
name: "worker",
|
|
5825
5918
|
description: "Background job processing",
|
|
5826
5919
|
dependencies: {
|
|
5920
|
+
"@geekmidas/audit": GEEKMIDAS_VERSIONS["@geekmidas/audit"],
|
|
5827
5921
|
"@geekmidas/constructs": GEEKMIDAS_VERSIONS["@geekmidas/constructs"],
|
|
5828
5922
|
"@geekmidas/envkit": GEEKMIDAS_VERSIONS["@geekmidas/envkit"],
|
|
5829
|
-
"@geekmidas/logger": GEEKMIDAS_VERSIONS["@geekmidas/logger"],
|
|
5830
5923
|
"@geekmidas/events": GEEKMIDAS_VERSIONS["@geekmidas/events"],
|
|
5924
|
+
"@geekmidas/logger": GEEKMIDAS_VERSIONS["@geekmidas/logger"],
|
|
5925
|
+
"@geekmidas/rate-limit": GEEKMIDAS_VERSIONS["@geekmidas/rate-limit"],
|
|
5926
|
+
"@geekmidas/schema": GEEKMIDAS_VERSIONS["@geekmidas/schema"],
|
|
5831
5927
|
"@hono/node-server": "~1.14.1",
|
|
5832
5928
|
hono: "~4.8.2",
|
|
5833
5929
|
pino: "~9.6.0"
|
|
@@ -5889,9 +5985,14 @@ export const config = envParser
|
|
|
5889
5985
|
{
|
|
5890
5986
|
path: getRoutePath("health.ts"),
|
|
5891
5987
|
content: `import { e } from '@geekmidas/constructs/endpoints';
|
|
5988
|
+
import { z } from 'zod';
|
|
5892
5989
|
|
|
5893
5990
|
export const healthEndpoint = e
|
|
5894
5991
|
.get('/health')
|
|
5992
|
+
.output(z.object({
|
|
5993
|
+
status: z.string(),
|
|
5994
|
+
timestamp: z.string(),
|
|
5995
|
+
}))
|
|
5895
5996
|
.handle(async () => ({
|
|
5896
5997
|
status: 'ok',
|
|
5897
5998
|
timestamp: new Date().toISOString(),
|