@geekmidas/cli 0.10.0 → 0.13.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/README.md +525 -0
- package/dist/bundler-B1qy9b-j.cjs +112 -0
- package/dist/bundler-B1qy9b-j.cjs.map +1 -0
- package/dist/bundler-DskIqW2t.mjs +111 -0
- package/dist/bundler-DskIqW2t.mjs.map +1 -0
- package/dist/{config-C9aXOHBe.cjs → config-AmInkU7k.cjs} +8 -8
- package/dist/config-AmInkU7k.cjs.map +1 -0
- package/dist/{config-BrkUalUh.mjs → config-DYULeEv8.mjs} +3 -3
- package/dist/config-DYULeEv8.mjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/encryption-C8H-38Yy.mjs +42 -0
- package/dist/encryption-C8H-38Yy.mjs.map +1 -0
- package/dist/encryption-Dyf_r1h-.cjs +44 -0
- package/dist/encryption-Dyf_r1h-.cjs.map +1 -0
- package/dist/index.cjs +2123 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2141 -192
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-CZLI4QTr.mjs → openapi-BfFlOBCG.mjs} +801 -38
- package/dist/openapi-BfFlOBCG.mjs.map +1 -0
- package/dist/{openapi-BeHLKcwP.cjs → openapi-Bt_1FDpT.cjs} +794 -31
- package/dist/openapi-Bt_1FDpT.cjs.map +1 -0
- package/dist/{openapi-react-query-o5iMi8tz.cjs → openapi-react-query-B-sNWHFU.cjs} +5 -5
- package/dist/openapi-react-query-B-sNWHFU.cjs.map +1 -0
- package/dist/{openapi-react-query-CcciaVu5.mjs → openapi-react-query-B6XTeGqS.mjs} +5 -5
- package/dist/openapi-react-query-B6XTeGqS.mjs.map +1 -0
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.d.cts.map +1 -1
- package/dist/openapi-react-query.d.mts.map +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/storage-BOOpAF8N.cjs +5 -0
- package/dist/storage-Bj1E26lU.cjs +187 -0
- package/dist/storage-Bj1E26lU.cjs.map +1 -0
- package/dist/storage-kSxTjkNb.mjs +133 -0
- package/dist/storage-kSxTjkNb.mjs.map +1 -0
- package/dist/storage-tgZSUnKl.mjs +3 -0
- package/dist/{types-b-vwGpqc.d.cts → types-BR0M2v_c.d.mts} +100 -1
- package/dist/types-BR0M2v_c.d.mts.map +1 -0
- package/dist/{types-DXgiA1sF.d.mts → types-BhkZc-vm.d.cts} +100 -1
- package/dist/types-BhkZc-vm.d.cts.map +1 -0
- package/examples/cron-example.ts +27 -27
- package/examples/env.ts +27 -27
- package/examples/function-example.ts +31 -31
- package/examples/gkm.config.json +20 -20
- package/examples/gkm.config.ts +8 -8
- package/examples/gkm.minimal.config.json +5 -5
- package/examples/gkm.production.config.json +25 -25
- package/examples/logger.ts +2 -2
- package/package.json +6 -6
- package/src/__tests__/EndpointGenerator.hooks.spec.ts +191 -191
- package/src/__tests__/config.spec.ts +55 -55
- package/src/__tests__/loadEnvFiles.spec.ts +93 -93
- package/src/__tests__/normalizeHooksConfig.spec.ts +58 -58
- package/src/__tests__/openapi-react-query.spec.ts +497 -497
- package/src/__tests__/openapi.spec.ts +428 -428
- package/src/__tests__/test-helpers.ts +76 -76
- package/src/auth/__tests__/credentials.spec.ts +204 -0
- package/src/auth/__tests__/index.spec.ts +168 -0
- package/src/auth/credentials.ts +187 -0
- package/src/auth/index.ts +226 -0
- package/src/build/__tests__/bundler.spec.ts +444 -0
- package/src/build/__tests__/index-new.spec.ts +474 -474
- package/src/build/__tests__/manifests.spec.ts +333 -333
- package/src/build/bundler.ts +210 -0
- package/src/build/endpoint-analyzer.ts +236 -0
- package/src/build/handler-templates.ts +1253 -0
- package/src/build/index.ts +260 -179
- package/src/build/manifests.ts +52 -52
- package/src/build/providerResolver.ts +145 -145
- package/src/build/types.ts +64 -43
- package/src/config.ts +39 -39
- package/src/deploy/__tests__/docker.spec.ts +111 -0
- package/src/deploy/__tests__/dokploy.spec.ts +245 -0
- package/src/deploy/__tests__/init.spec.ts +662 -0
- package/src/deploy/docker.ts +128 -0
- package/src/deploy/dokploy.ts +204 -0
- package/src/deploy/index.ts +136 -0
- package/src/deploy/init.ts +484 -0
- package/src/deploy/types.ts +48 -0
- package/src/dev/__tests__/index.spec.ts +266 -266
- package/src/dev/index.ts +647 -601
- package/src/docker/__tests__/compose.spec.ts +531 -0
- package/src/docker/__tests__/templates.spec.ts +280 -0
- package/src/docker/compose.ts +273 -0
- package/src/docker/index.ts +230 -0
- package/src/docker/templates.ts +446 -0
- package/src/generators/CronGenerator.ts +72 -72
- package/src/generators/EndpointGenerator.ts +699 -398
- package/src/generators/FunctionGenerator.ts +84 -84
- package/src/generators/Generator.ts +72 -72
- package/src/generators/OpenApiTsGenerator.ts +577 -577
- package/src/generators/SubscriberGenerator.ts +124 -124
- package/src/generators/__tests__/CronGenerator.spec.ts +433 -433
- package/src/generators/__tests__/EndpointGenerator.spec.ts +532 -382
- package/src/generators/__tests__/FunctionGenerator.spec.ts +244 -244
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +397 -382
- package/src/generators/index.ts +4 -4
- package/src/index.ts +623 -201
- package/src/init/__tests__/generators.spec.ts +334 -334
- package/src/init/__tests__/init.spec.ts +332 -332
- package/src/init/__tests__/utils.spec.ts +89 -89
- package/src/init/generators/config.ts +175 -175
- package/src/init/generators/docker.ts +41 -41
- package/src/init/generators/env.ts +72 -72
- package/src/init/generators/index.ts +1 -1
- package/src/init/generators/models.ts +64 -64
- package/src/init/generators/monorepo.ts +161 -161
- package/src/init/generators/package.ts +71 -71
- package/src/init/generators/source.ts +6 -6
- package/src/init/index.ts +203 -208
- package/src/init/templates/api.ts +115 -115
- package/src/init/templates/index.ts +75 -75
- package/src/init/templates/minimal.ts +98 -98
- package/src/init/templates/serverless.ts +89 -89
- package/src/init/templates/worker.ts +98 -98
- package/src/init/utils.ts +54 -56
- package/src/openapi-react-query.ts +194 -194
- package/src/openapi.ts +63 -63
- package/src/secrets/__tests__/encryption.spec.ts +226 -0
- package/src/secrets/__tests__/generator.spec.ts +319 -0
- package/src/secrets/__tests__/index.spec.ts +91 -0
- package/src/secrets/__tests__/storage.spec.ts +611 -0
- package/src/secrets/encryption.ts +91 -0
- package/src/secrets/generator.ts +164 -0
- package/src/secrets/index.ts +383 -0
- package/src/secrets/storage.ts +192 -0
- package/src/secrets/types.ts +53 -0
- package/src/types.ts +295 -176
- package/tsdown.config.ts +11 -8
- package/dist/config-BrkUalUh.mjs.map +0 -1
- package/dist/config-C9aXOHBe.cjs.map +0 -1
- package/dist/openapi-BeHLKcwP.cjs.map +0 -1
- package/dist/openapi-CZLI4QTr.mjs.map +0 -1
- package/dist/openapi-react-query-CcciaVu5.mjs.map +0 -1
- package/dist/openapi-react-query-o5iMi8tz.cjs.map +0 -1
- package/dist/types-DXgiA1sF.d.mts.map +0 -1
- package/dist/types-b-vwGpqc.d.cts.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
AWSApiGatewayConfig,
|
|
3
|
+
AWSLambdaConfig,
|
|
4
|
+
BuildOptions,
|
|
5
|
+
GkmConfig,
|
|
6
|
+
LegacyProvider,
|
|
7
|
+
MainProvider,
|
|
8
|
+
ProvidersConfig,
|
|
9
|
+
ServerConfig,
|
|
10
10
|
} from '../types';
|
|
11
11
|
|
|
12
12
|
export interface ResolvedProviders {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
providers: LegacyProvider[];
|
|
14
|
+
enableOpenApi: boolean;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -19,166 +19,166 @@ export interface ResolvedProviders {
|
|
|
19
19
|
* to the internal legacy format for backward compatibility
|
|
20
20
|
*/
|
|
21
21
|
export function resolveProviders(
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
config: GkmConfig,
|
|
23
|
+
options: BuildOptions,
|
|
24
24
|
): ResolvedProviders {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
25
|
+
const providers: LegacyProvider[] = [];
|
|
26
|
+
let enableOpenApi = options.enableOpenApi || false;
|
|
27
|
+
|
|
28
|
+
// Handle legacy providers option (deprecated)
|
|
29
|
+
if (options.providers) {
|
|
30
|
+
return {
|
|
31
|
+
providers: options.providers,
|
|
32
|
+
enableOpenApi,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Handle new provider option
|
|
37
|
+
if (options.provider) {
|
|
38
|
+
const resolvedProviders = resolveMainProvider(
|
|
39
|
+
options.provider,
|
|
40
|
+
config.providers,
|
|
41
|
+
);
|
|
42
|
+
providers.push(...resolvedProviders.providers);
|
|
43
|
+
enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
|
|
44
|
+
}
|
|
45
|
+
// Default: build all configured providers
|
|
46
|
+
else if (config.providers) {
|
|
47
|
+
const resolvedProviders = resolveAllConfiguredProviders(config.providers);
|
|
48
|
+
providers.push(...resolvedProviders.providers);
|
|
49
|
+
enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
|
|
50
|
+
}
|
|
51
|
+
// Fallback: use default AWS configuration
|
|
52
|
+
else {
|
|
53
|
+
providers.push('aws-apigatewayv2', 'aws-lambda');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
providers: [...new Set(providers)], // Remove duplicates
|
|
58
|
+
enableOpenApi,
|
|
59
|
+
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
function resolveMainProvider(
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
mainProvider: MainProvider,
|
|
64
|
+
providersConfig?: ProvidersConfig,
|
|
65
65
|
): ResolvedProviders {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
66
|
+
const providers: LegacyProvider[] = [];
|
|
67
|
+
let enableOpenApi = false;
|
|
68
|
+
|
|
69
|
+
if (mainProvider === 'aws') {
|
|
70
|
+
const awsConfig = providersConfig?.aws;
|
|
71
|
+
|
|
72
|
+
// Resolve API Gateway providers
|
|
73
|
+
if (awsConfig?.apiGateway) {
|
|
74
|
+
if (isEnabled(awsConfig.apiGateway.v1)) {
|
|
75
|
+
providers.push('aws-apigatewayv1');
|
|
76
|
+
}
|
|
77
|
+
if (isEnabled(awsConfig.apiGateway.v2)) {
|
|
78
|
+
providers.push('aws-apigatewayv2');
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
// Default: enable v2 if no specific config
|
|
82
|
+
providers.push('aws-apigatewayv2');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Resolve Lambda providers
|
|
86
|
+
if (awsConfig?.lambda) {
|
|
87
|
+
if (
|
|
88
|
+
isEnabled(awsConfig.lambda.functions) ||
|
|
89
|
+
isEnabled(awsConfig.lambda.crons)
|
|
90
|
+
) {
|
|
91
|
+
providers.push('aws-lambda');
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
// Default: enable lambda if no specific config
|
|
95
|
+
providers.push('aws-lambda');
|
|
96
|
+
}
|
|
97
|
+
} else if (mainProvider === 'server') {
|
|
98
|
+
providers.push('server');
|
|
99
|
+
const serverConfig = providersConfig?.server;
|
|
100
|
+
|
|
101
|
+
if (typeof serverConfig === 'object' && serverConfig?.enableOpenApi) {
|
|
102
|
+
enableOpenApi = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { providers, enableOpenApi };
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
function resolveAllConfiguredProviders(
|
|
110
|
-
|
|
110
|
+
providersConfig: ProvidersConfig,
|
|
111
111
|
): ResolvedProviders {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
112
|
+
const providers: LegacyProvider[] = [];
|
|
113
|
+
let enableOpenApi = false;
|
|
114
|
+
|
|
115
|
+
// AWS providers
|
|
116
|
+
if (providersConfig.aws) {
|
|
117
|
+
const awsProviders = resolveMainProvider('aws', providersConfig);
|
|
118
|
+
providers.push(...awsProviders.providers);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Server provider
|
|
122
|
+
if (providersConfig.server && isEnabled(providersConfig.server)) {
|
|
123
|
+
providers.push('server');
|
|
124
|
+
if (
|
|
125
|
+
typeof providersConfig.server === 'object' &&
|
|
126
|
+
providersConfig.server.enableOpenApi
|
|
127
|
+
) {
|
|
128
|
+
enableOpenApi = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return { providers, enableOpenApi };
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
function isEnabled(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
config:
|
|
137
|
+
| boolean
|
|
138
|
+
| AWSApiGatewayConfig
|
|
139
|
+
| AWSLambdaConfig
|
|
140
|
+
| ServerConfig
|
|
141
|
+
| undefined,
|
|
142
142
|
): boolean {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
if (config === undefined) return false;
|
|
144
|
+
if (typeof config === 'boolean') return config;
|
|
145
|
+
return config.enabled !== false; // Default to true if enabled is not explicitly false
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
149
149
|
* Gets configuration for a specific AWS service
|
|
150
150
|
*/
|
|
151
151
|
export function getAWSServiceConfig<
|
|
152
|
-
|
|
152
|
+
T extends AWSApiGatewayConfig | AWSLambdaConfig,
|
|
153
153
|
>(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
config: GkmConfig,
|
|
155
|
+
service: 'apiGateway' | 'lambda',
|
|
156
|
+
subService?: 'v1' | 'v2' | 'functions' | 'crons',
|
|
157
157
|
): T | undefined {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
158
|
+
const awsConfig = config.providers?.aws;
|
|
159
|
+
if (!awsConfig) return undefined;
|
|
160
|
+
|
|
161
|
+
if (service === 'apiGateway' && awsConfig.apiGateway) {
|
|
162
|
+
const apiConfig = subService
|
|
163
|
+
? awsConfig.apiGateway[subService as 'v1' | 'v2']
|
|
164
|
+
: undefined;
|
|
165
|
+
return typeof apiConfig === 'object' ? (apiConfig as T) : undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (service === 'lambda' && awsConfig.lambda) {
|
|
169
|
+
const lambdaConfig = subService
|
|
170
|
+
? awsConfig.lambda[subService as 'functions' | 'crons']
|
|
171
|
+
: undefined;
|
|
172
|
+
return typeof lambdaConfig === 'object' ? (lambdaConfig as T) : undefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return undefined;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Gets server configuration
|
|
180
180
|
*/
|
|
181
181
|
export function getServerConfig(config: GkmConfig): ServerConfig | undefined {
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
const serverConfig = config.providers?.server;
|
|
183
|
+
return typeof serverConfig === 'object' ? serverConfig : undefined;
|
|
184
184
|
}
|
package/src/build/types.ts
CHANGED
|
@@ -5,68 +5,89 @@ import type { Function } from '@geekmidas/constructs/functions';
|
|
|
5
5
|
import type { CronInfo, FunctionInfo, RouteInfo } from '../types';
|
|
6
6
|
|
|
7
7
|
export interface ProcessedEndpoint {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
file: string;
|
|
9
|
+
exportName: string;
|
|
10
|
+
endpoint: Endpoint<any, any, any, any, any, any>;
|
|
11
|
+
routeInfo: RouteInfo;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface ProcessedFunction {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
file: string;
|
|
16
|
+
exportName: string;
|
|
17
|
+
fn: Function<any, any, any, any, any>;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export interface ProcessedCron {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
file: string;
|
|
22
|
+
exportName: string;
|
|
23
|
+
cron: Cron<any, any, any, any>;
|
|
24
|
+
schedule?: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface NormalizedTelescopeConfig {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
/** Path to user's telescope module (if provided) */
|
|
30
|
+
telescopePath?: string;
|
|
31
|
+
/** Import pattern for telescope (e.g., '{ telescope }' or 'telescope') */
|
|
32
|
+
telescopeImportPattern?: string;
|
|
33
|
+
/** UI path for telescope dashboard */
|
|
34
|
+
path: string;
|
|
35
|
+
ignore: string[];
|
|
36
|
+
recordBody: boolean;
|
|
37
|
+
maxEntries: number;
|
|
38
|
+
websocket: boolean;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export interface NormalizedStudioConfig {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
/** Path to user's studio module (if provided) */
|
|
44
|
+
studioPath?: string;
|
|
45
|
+
/** Import pattern for studio (e.g., '{ studio }' or 'studio') */
|
|
46
|
+
studioImportPattern?: string;
|
|
47
|
+
/** UI path for studio dashboard */
|
|
48
|
+
path: string;
|
|
49
|
+
/** Database schema to introspect */
|
|
50
|
+
schema: string;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface NormalizedHooksConfig {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
/** Path to server hooks module */
|
|
55
|
+
serverHooksPath: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface NormalizedProductionConfig {
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
bundle: boolean;
|
|
61
|
+
minify: boolean;
|
|
62
|
+
healthCheck: string;
|
|
63
|
+
gracefulShutdown: boolean;
|
|
64
|
+
external: string[];
|
|
65
|
+
subscribers: 'include' | 'exclude';
|
|
66
|
+
openapi: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Enable build-time optimized handler generation
|
|
69
|
+
* When true, generates specialized handlers based on endpoint tier:
|
|
70
|
+
* - minimal: Near-raw-Hono performance for simple endpoints
|
|
71
|
+
* - standard: Optimized handlers for auth/services
|
|
72
|
+
* - full: Uses HonoEndpoint.addRoutes for complex endpoints
|
|
73
|
+
*/
|
|
74
|
+
optimizedHandlers: boolean;
|
|
56
75
|
}
|
|
57
76
|
|
|
58
77
|
export interface BuildContext {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
78
|
+
envParserPath: string;
|
|
79
|
+
envParserImportPattern: string;
|
|
80
|
+
loggerPath: string;
|
|
81
|
+
loggerImportPattern: string;
|
|
82
|
+
telescope?: NormalizedTelescopeConfig;
|
|
83
|
+
studio?: NormalizedStudioConfig;
|
|
84
|
+
hooks?: NormalizedHooksConfig;
|
|
85
|
+
/** Production build configuration */
|
|
86
|
+
production?: NormalizedProductionConfig;
|
|
66
87
|
}
|
|
67
88
|
|
|
68
89
|
export interface ProviderBuildResult {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
90
|
+
routes: RouteInfo[];
|
|
91
|
+
functions: FunctionInfo[];
|
|
92
|
+
crons: CronInfo[];
|
|
72
93
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
3
|
import type { GkmConfig } from './types.ts';
|
|
4
4
|
|
|
5
5
|
export type { GkmConfig } from './types.ts';
|
|
@@ -21,12 +21,12 @@ export type { GkmConfig } from './types.ts';
|
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
23
|
export function defineConfig(config: GkmConfig): GkmConfig {
|
|
24
|
-
|
|
24
|
+
return config;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface ParsedModuleConfig {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
path: string;
|
|
29
|
+
importPattern: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -47,47 +47,47 @@ export interface ParsedModuleConfig {
|
|
|
47
47
|
* // { path: './src/config/env', importPattern: '{ myEnv as envParser }' }
|
|
48
48
|
*/
|
|
49
49
|
export function parseModuleConfig(
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
configString: string,
|
|
51
|
+
defaultAlias: string,
|
|
52
52
|
): ParsedModuleConfig {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
const parts = configString.split('#');
|
|
54
|
+
const path = parts[0] ?? configString;
|
|
55
|
+
const exportName = parts[1];
|
|
56
|
+
const importPattern = !exportName
|
|
57
|
+
? defaultAlias
|
|
58
|
+
: exportName === defaultAlias
|
|
59
|
+
? `{ ${defaultAlias} }`
|
|
60
|
+
: `{ ${exportName} as ${defaultAlias} }`;
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
return { path, importPattern };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
export async function loadConfig(
|
|
66
|
-
|
|
66
|
+
cwd: string = process.cwd(),
|
|
67
67
|
): Promise<GkmConfig> {
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const files = ['gkm.config.json', 'gkm.config.ts', 'gkm.config.js'];
|
|
69
|
+
let configPath = '';
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
for (const file of files) {
|
|
72
|
+
const path = join(cwd, file);
|
|
73
|
+
if (existsSync(path)) {
|
|
74
|
+
configPath = path;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
if (!configPath) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'Configuration file not found. Please create gkm.config.json, gkm.config.ts, or gkm.config.js in the project root.',
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
try {
|
|
86
|
+
const config = await import(configPath);
|
|
87
|
+
return config.default;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Failed to load gkm.config.json: ${(error as Error).message}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
93
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import type { GkmConfig } from '../../types';
|
|
3
|
+
import { getImageRef, resolveDockerConfig } from '../docker';
|
|
4
|
+
|
|
5
|
+
describe('getImageRef', () => {
|
|
6
|
+
it('should return image with registry prefix', () => {
|
|
7
|
+
const result = getImageRef('ghcr.io/myorg', 'myapp', 'v1.0.0');
|
|
8
|
+
expect(result).toBe('ghcr.io/myorg/myapp:v1.0.0');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should return image without registry when undefined', () => {
|
|
12
|
+
const result = getImageRef(undefined, 'myapp', 'v1.0.0');
|
|
13
|
+
expect(result).toBe('myapp:v1.0.0');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should handle different tag formats', () => {
|
|
17
|
+
expect(getImageRef('docker.io', 'app', 'latest')).toBe(
|
|
18
|
+
'docker.io/app:latest',
|
|
19
|
+
);
|
|
20
|
+
expect(getImageRef('docker.io', 'app', 'sha-abc123')).toBe(
|
|
21
|
+
'docker.io/app:sha-abc123',
|
|
22
|
+
);
|
|
23
|
+
expect(getImageRef('docker.io', 'app', '1.2.3-beta.1')).toBe(
|
|
24
|
+
'docker.io/app:1.2.3-beta.1',
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should handle registry with port', () => {
|
|
29
|
+
const result = getImageRef('localhost:5000', 'myapp', 'dev');
|
|
30
|
+
expect(result).toBe('localhost:5000/myapp:dev');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should handle nested registry paths', () => {
|
|
34
|
+
const result = getImageRef('gcr.io/my-project/images', 'api', 'prod');
|
|
35
|
+
expect(result).toBe('gcr.io/my-project/images/api:prod');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('resolveDockerConfig', () => {
|
|
40
|
+
it('should return empty config when docker not configured', () => {
|
|
41
|
+
const config: GkmConfig = {
|
|
42
|
+
routes: './src/endpoints',
|
|
43
|
+
envParser: './src/env',
|
|
44
|
+
logger: './src/logger',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const dockerConfig = resolveDockerConfig(config);
|
|
48
|
+
|
|
49
|
+
expect(dockerConfig.registry).toBeUndefined();
|
|
50
|
+
expect(dockerConfig.imageName).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should return registry from docker config', () => {
|
|
54
|
+
const config: GkmConfig = {
|
|
55
|
+
routes: './src/endpoints',
|
|
56
|
+
envParser: './src/env',
|
|
57
|
+
logger: './src/logger',
|
|
58
|
+
docker: {
|
|
59
|
+
registry: 'ghcr.io/myorg',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const dockerConfig = resolveDockerConfig(config);
|
|
64
|
+
|
|
65
|
+
expect(dockerConfig.registry).toBe('ghcr.io/myorg');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should return imageName from docker config', () => {
|
|
69
|
+
const config: GkmConfig = {
|
|
70
|
+
routes: './src/endpoints',
|
|
71
|
+
envParser: './src/env',
|
|
72
|
+
logger: './src/logger',
|
|
73
|
+
docker: {
|
|
74
|
+
imageName: 'my-api',
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const dockerConfig = resolveDockerConfig(config);
|
|
79
|
+
|
|
80
|
+
expect(dockerConfig.imageName).toBe('my-api');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should return both registry and imageName', () => {
|
|
84
|
+
const config: GkmConfig = {
|
|
85
|
+
routes: './src/endpoints',
|
|
86
|
+
envParser: './src/env',
|
|
87
|
+
logger: './src/logger',
|
|
88
|
+
docker: {
|
|
89
|
+
registry: 'docker.io/company',
|
|
90
|
+
imageName: 'backend-api',
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const dockerConfig = resolveDockerConfig(config);
|
|
95
|
+
|
|
96
|
+
expect(dockerConfig.registry).toBe('docker.io/company');
|
|
97
|
+
expect(dockerConfig.imageName).toBe('backend-api');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should handle empty docker object', () => {
|
|
101
|
+
const config: GkmConfig = {
|
|
102
|
+
routes: './src/endpoints',
|
|
103
|
+
docker: {},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const dockerConfig = resolveDockerConfig(config);
|
|
107
|
+
|
|
108
|
+
expect(dockerConfig.registry).toBeUndefined();
|
|
109
|
+
expect(dockerConfig.imageName).toBeUndefined();
|
|
110
|
+
});
|
|
111
|
+
});
|