@geekmidas/cli 1.2.3 → 1.4.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/CHANGELOG.md +12 -0
- package/dist/{CachedStateProvider-DVyKfaMm.mjs → CachedStateProvider-BDq5WqSy.mjs} +1 -1
- package/dist/{CachedStateProvider-DVyKfaMm.mjs.map → CachedStateProvider-BDq5WqSy.mjs.map} +1 -1
- package/dist/CachedStateProvider-CI61keQ1.mjs +3 -0
- package/dist/{HostingerProvider-DqUq6e9i.mjs → HostingerProvider-B9N-TKbp.mjs} +2 -2
- package/dist/{HostingerProvider-DqUq6e9i.mjs.map → HostingerProvider-B9N-TKbp.mjs.map} +1 -1
- package/dist/{LocalStateProvider-DxoSaWUV.mjs → LocalStateProvider-BDm7ZqJo.mjs} +1 -1
- package/dist/{LocalStateProvider-DxoSaWUV.mjs.map → LocalStateProvider-BDm7ZqJo.mjs.map} +1 -1
- package/dist/{Route53Provider-KUAX3vz9.mjs → Route53Provider-DOWmFnwN.mjs} +2 -2
- package/dist/{Route53Provider-KUAX3vz9.mjs.map → Route53Provider-DOWmFnwN.mjs.map} +1 -1
- package/dist/{Route53Provider-CpRIqu69.cjs → Route53Provider-xrWuBXih.cjs} +2 -2
- package/dist/{Route53Provider-CpRIqu69.cjs.map → Route53Provider-xrWuBXih.cjs.map} +1 -1
- package/dist/{SSMStateProvider-D79o_JjM.cjs → SSMStateProvider-DGrqYll0.cjs} +8 -4
- package/dist/SSMStateProvider-DGrqYll0.cjs.map +1 -0
- package/dist/{SSMStateProvider-BjCi_58g.mjs → SSMStateProvider-DT0WV-E_.mjs} +9 -4
- package/dist/SSMStateProvider-DT0WV-E_.mjs.map +1 -0
- package/dist/{bundler-BqTN5Dj5.mjs → bundler-DgXsOSxc.mjs} +3 -3
- package/dist/{bundler-BqTN5Dj5.mjs.map → bundler-DgXsOSxc.mjs.map} +1 -1
- package/dist/chunk-Duj1WY3L.mjs +7 -0
- package/dist/{config-BQ4a36Rq.mjs → config-C1bidhvG.mjs} +2 -2
- package/dist/{config-BQ4a36Rq.mjs.map → config-C1bidhvG.mjs.map} +1 -1
- package/dist/{config-Bayob8pB.cjs → config-C1dM7aZb.cjs} +2 -2
- package/dist/{config-Bayob8pB.cjs.map → config-C1dM7aZb.cjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +2 -2
- package/dist/{credentials-DT1dSxIx.mjs → credentials-s1kLcIzK.mjs} +1 -1
- package/dist/{credentials-DT1dSxIx.mjs.map → credentials-s1kLcIzK.mjs.map} +1 -1
- package/dist/deploy/sniffer-routes-worker.cjs +65 -0
- package/dist/deploy/sniffer-routes-worker.cjs.map +1 -0
- package/dist/deploy/sniffer-routes-worker.d.cts +1 -0
- package/dist/deploy/sniffer-routes-worker.d.mts +1 -0
- package/dist/deploy/sniffer-routes-worker.mjs +64 -0
- package/dist/deploy/sniffer-routes-worker.mjs.map +1 -0
- package/dist/dokploy-api-DSJYNx88.mjs +3 -0
- package/dist/{dokploy-api-7k3t7_zd.mjs → dokploy-api-z0833e7r.mjs} +1 -1
- package/dist/{dokploy-api-7k3t7_zd.mjs.map → dokploy-api-z0833e7r.mjs.map} +1 -1
- package/dist/{encryption-JtMsiGNp.mjs → encryption-BOH5M-f-.mjs} +1 -1
- package/dist/{encryption-JtMsiGNp.mjs.map → encryption-BOH5M-f-.mjs.map} +1 -1
- package/dist/encryption-a9TNMWav.mjs +3 -0
- package/dist/{index-Bi9vGQJy.d.mts → index-DvpWzLD7.d.mts} +5 -2
- package/dist/index-DvpWzLD7.d.mts.map +1 -0
- package/dist/{index-CufAAnge.d.cts → index-DzmZ6SUW.d.cts} +4 -1
- package/dist/index-DzmZ6SUW.d.cts.map +1 -0
- package/dist/index.cjs +27 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +42 -27
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-NthphEWK.mjs → openapi-9k6a6VA4.mjs} +2 -2
- package/dist/{openapi-NthphEWK.mjs.map → openapi-9k6a6VA4.mjs.map} +1 -1
- package/dist/{openapi-ZhO7wwya.cjs → openapi-Dcja4e1C.cjs} +2 -2
- package/dist/{openapi-ZhO7wwya.cjs.map → openapi-Dcja4e1C.cjs.map} +1 -1
- package/dist/{openapi-react-query-DGEkD39r.mjs → openapi-react-query-DaTMSPD5.mjs} +1 -1
- package/dist/{openapi-react-query-DGEkD39r.mjs.map → openapi-react-query-DaTMSPD5.mjs.map} +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{storage-BMW6yLu3.mjs → storage-DmCbr6DI.mjs} +1 -1
- package/dist/{storage-BMW6yLu3.mjs.map → storage-DmCbr6DI.mjs.map} +1 -1
- package/dist/{storage-D8XzjVaO.mjs → storage-Dx_jZbq6.mjs} +1 -1
- package/dist/{types-BldpmqQX.d.mts → types-B9UZ7fOG.d.mts} +1 -1
- package/dist/{types-BldpmqQX.d.mts.map → types-B9UZ7fOG.d.mts.map} +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +1 -1
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-CASoZOjs.mjs → workspace-Cb_I7oCJ.mjs} +5 -8
- package/dist/{workspace-CASoZOjs.mjs.map → workspace-Cb_I7oCJ.mjs.map} +1 -1
- package/dist/{workspace-BMJE18LV.cjs → workspace-CeFgIDC-.cjs} +3 -2
- package/dist/{workspace-BMJE18LV.cjs.map → workspace-CeFgIDC-.cjs.map} +1 -1
- package/package.json +3 -3
- package/src/deploy/SSMStateProvider.ts +14 -3
- package/src/deploy/StateProvider.ts +5 -1
- package/src/deploy/__tests__/SSMStateProvider.spec.ts +12 -0
- package/src/deploy/__tests__/createStateProvider.spec.ts +10 -0
- package/src/deploy/__tests__/env-resolver.spec.ts +145 -2
- package/src/deploy/__tests__/index.spec.ts +393 -5
- package/src/deploy/env-resolver.ts +10 -0
- package/src/deploy/index.ts +11 -0
- package/src/init/generators/monorepo.ts +3 -1
- package/src/init/generators/web.ts +6 -2
- package/src/workspace/schema.ts +2 -0
- package/tsdown.config.ts +1 -0
- package/dist/CachedStateProvider-OiFUGr7p.mjs +0 -3
- package/dist/SSMStateProvider-BjCi_58g.mjs.map +0 -1
- package/dist/SSMStateProvider-D79o_JjM.cjs.map +0 -1
- package/dist/dokploy-api-CHa8G51l.mjs +0 -3
- package/dist/encryption-UUmaWAmz.mjs +0 -3
- package/dist/index-Bi9vGQJy.d.mts.map +0 -1
- package/dist/index-CufAAnge.d.cts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"@geekmidas/constructs": "~1.0.0",
|
|
57
57
|
"@geekmidas/envkit": "~1.0.0",
|
|
58
58
|
"@geekmidas/errors": "~1.0.0",
|
|
59
|
-
"@geekmidas/
|
|
60
|
-
"@geekmidas/
|
|
59
|
+
"@geekmidas/schema": "~1.0.0",
|
|
60
|
+
"@geekmidas/logger": "~1.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
@@ -22,6 +22,8 @@ export interface SSMStateProviderOptions {
|
|
|
22
22
|
workspaceName: string;
|
|
23
23
|
/** AWS region */
|
|
24
24
|
region?: AwsRegion;
|
|
25
|
+
/** AWS profile name (optional - uses default credential chain if not provided) */
|
|
26
|
+
profile?: string;
|
|
25
27
|
/** AWS credentials (optional - uses default credential chain if not provided) */
|
|
26
28
|
credentials?: SSMClientConfig['credentials'];
|
|
27
29
|
/** Custom endpoint (for LocalStack or other S3-compatible services) */
|
|
@@ -44,12 +46,21 @@ export class SSMStateProvider implements StateProvider {
|
|
|
44
46
|
* Create an SSMStateProvider with a new SSMClient.
|
|
45
47
|
*/
|
|
46
48
|
static create(options: SSMStateProviderOptions): SSMStateProvider {
|
|
47
|
-
const
|
|
49
|
+
const clientConfig: SSMClientConfig = {
|
|
48
50
|
region: options.region,
|
|
49
|
-
credentials: options.credentials,
|
|
50
51
|
endpoint: options.endpoint,
|
|
51
|
-
}
|
|
52
|
+
};
|
|
52
53
|
|
|
54
|
+
// Use profile credentials if specified, otherwise use provided credentials or default chain
|
|
55
|
+
if (options.profile) {
|
|
56
|
+
// Dynamic import to avoid requiring @aws-sdk/credential-providers when not using profiles
|
|
57
|
+
const { fromIni } = require('@aws-sdk/credential-providers');
|
|
58
|
+
clientConfig.credentials = fromIni({ profile: options.profile });
|
|
59
|
+
} else if (options.credentials) {
|
|
60
|
+
clientConfig.credentials = options.credentials;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const client = new SSMClient(clientConfig);
|
|
53
64
|
return new SSMStateProvider(options.workspaceName, client);
|
|
54
65
|
}
|
|
55
66
|
|
|
@@ -79,6 +79,8 @@ export interface SSMStateConfig {
|
|
|
79
79
|
provider: 'ssm';
|
|
80
80
|
/** AWS region (required for SSM provider) */
|
|
81
81
|
region: AwsRegion;
|
|
82
|
+
/** AWS profile name (optional - uses default credential chain if not provided) */
|
|
83
|
+
profile?: string;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/**
|
|
@@ -157,10 +159,12 @@ export async function createStateProvider(
|
|
|
157
159
|
const { SSMStateProvider } = await import('./SSMStateProvider');
|
|
158
160
|
const { CachedStateProvider } = await import('./CachedStateProvider');
|
|
159
161
|
|
|
162
|
+
const ssmConfig = config as SSMStateConfig;
|
|
160
163
|
const local = new LocalStateProvider(workspaceRoot);
|
|
161
164
|
const ssm = SSMStateProvider.create({
|
|
162
165
|
workspaceName,
|
|
163
|
-
region:
|
|
166
|
+
region: ssmConfig.region,
|
|
167
|
+
profile: ssmConfig.profile,
|
|
164
168
|
});
|
|
165
169
|
|
|
166
170
|
return new CachedStateProvider(ssm, local);
|
|
@@ -75,6 +75,18 @@ describe('SSMStateProvider', () => {
|
|
|
75
75
|
expect(provider).toBeInstanceOf(SSMStateProvider);
|
|
76
76
|
expect(provider.workspaceName).toBe('my-workspace');
|
|
77
77
|
});
|
|
78
|
+
|
|
79
|
+
it('should create provider with profile option', () => {
|
|
80
|
+
const provider = SSMStateProvider.create({
|
|
81
|
+
workspaceName: 'my-workspace',
|
|
82
|
+
region: 'us-west-2',
|
|
83
|
+
profile: 'my-profile',
|
|
84
|
+
endpoint: LOCALSTACK_ENDPOINT,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(provider).toBeInstanceOf(SSMStateProvider);
|
|
88
|
+
expect(provider.workspaceName).toBe('my-workspace');
|
|
89
|
+
});
|
|
78
90
|
});
|
|
79
91
|
|
|
80
92
|
describe('read', () => {
|
|
@@ -93,6 +93,16 @@ describe('createStateProvider', () => {
|
|
|
93
93
|
|
|
94
94
|
expect(provider).toBeInstanceOf(CachedStateProvider);
|
|
95
95
|
});
|
|
96
|
+
|
|
97
|
+
it('should create CachedStateProvider for ssm config with profile', async () => {
|
|
98
|
+
const provider = await createStateProvider({
|
|
99
|
+
config: { provider: 'ssm', region: 'us-east-1', profile: 'my-profile' },
|
|
100
|
+
workspaceRoot: testDir,
|
|
101
|
+
workspaceName: 'test-workspace',
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(provider).toBeInstanceOf(CachedStateProvider);
|
|
105
|
+
});
|
|
96
106
|
});
|
|
97
107
|
|
|
98
108
|
describe('custom provider', () => {
|
|
@@ -295,6 +295,9 @@ describe('resolveEnvVar', () => {
|
|
|
295
295
|
it('should resolve custom variable from userSecrets.custom', () => {
|
|
296
296
|
const context = createContext({
|
|
297
297
|
userSecrets: {
|
|
298
|
+
stage: 'production',
|
|
299
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
300
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
298
301
|
custom: { MY_API_KEY: 'secret-api-key' },
|
|
299
302
|
urls: {},
|
|
300
303
|
services: {},
|
|
@@ -307,6 +310,9 @@ describe('resolveEnvVar', () => {
|
|
|
307
310
|
it('should resolve URL variables from userSecrets.urls', () => {
|
|
308
311
|
const context = createContext({
|
|
309
312
|
userSecrets: {
|
|
313
|
+
stage: 'production',
|
|
314
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
315
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
310
316
|
custom: {},
|
|
311
317
|
urls: { DATABASE_URL: 'postgresql://external:5432/db' },
|
|
312
318
|
services: {},
|
|
@@ -321,9 +327,19 @@ describe('resolveEnvVar', () => {
|
|
|
321
327
|
it('should resolve POSTGRES_PASSWORD from userSecrets.services', () => {
|
|
322
328
|
const context = createContext({
|
|
323
329
|
userSecrets: {
|
|
330
|
+
stage: 'production',
|
|
331
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
332
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
324
333
|
custom: {},
|
|
325
334
|
urls: {},
|
|
326
|
-
services: {
|
|
335
|
+
services: {
|
|
336
|
+
postgres: {
|
|
337
|
+
host: 'localhost',
|
|
338
|
+
port: 5432,
|
|
339
|
+
username: 'postgres',
|
|
340
|
+
password: 'pg-password',
|
|
341
|
+
},
|
|
342
|
+
},
|
|
327
343
|
},
|
|
328
344
|
});
|
|
329
345
|
|
|
@@ -333,9 +349,19 @@ describe('resolveEnvVar', () => {
|
|
|
333
349
|
it('should resolve REDIS_PASSWORD from userSecrets.services', () => {
|
|
334
350
|
const context = createContext({
|
|
335
351
|
userSecrets: {
|
|
352
|
+
stage: 'production',
|
|
353
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
354
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
336
355
|
custom: {},
|
|
337
356
|
urls: {},
|
|
338
|
-
services: {
|
|
357
|
+
services: {
|
|
358
|
+
redis: {
|
|
359
|
+
host: 'localhost',
|
|
360
|
+
port: 6379,
|
|
361
|
+
username: 'default',
|
|
362
|
+
password: 'redis-password',
|
|
363
|
+
},
|
|
364
|
+
},
|
|
339
365
|
},
|
|
340
366
|
});
|
|
341
367
|
|
|
@@ -347,6 +373,86 @@ describe('resolveEnvVar', () => {
|
|
|
347
373
|
|
|
348
374
|
expect(resolveEnvVar('UNKNOWN_VAR', context)).toBeUndefined();
|
|
349
375
|
});
|
|
376
|
+
|
|
377
|
+
describe('dependency URLs', () => {
|
|
378
|
+
it('should resolve AUTH_URL from dependencyUrls', () => {
|
|
379
|
+
const context = createContext({
|
|
380
|
+
dependencyUrls: { auth: 'https://auth.example.com' },
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
expect(resolveEnvVar('AUTH_URL', context)).toBe(
|
|
384
|
+
'https://auth.example.com',
|
|
385
|
+
);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('should resolve API_URL from dependencyUrls', () => {
|
|
389
|
+
const context = createContext({
|
|
390
|
+
dependencyUrls: { api: 'https://api.example.com' },
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
expect(resolveEnvVar('API_URL', context)).toBe('https://api.example.com');
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('should resolve any {DEP}_URL pattern from dependencyUrls', () => {
|
|
397
|
+
const context = createContext({
|
|
398
|
+
dependencyUrls: {
|
|
399
|
+
payments: 'https://payments.example.com',
|
|
400
|
+
notifications: 'https://notifications.example.com',
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
expect(resolveEnvVar('PAYMENTS_URL', context)).toBe(
|
|
405
|
+
'https://payments.example.com',
|
|
406
|
+
);
|
|
407
|
+
expect(resolveEnvVar('NOTIFICATIONS_URL', context)).toBe(
|
|
408
|
+
'https://notifications.example.com',
|
|
409
|
+
);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it('should return undefined for missing dependency URL', () => {
|
|
413
|
+
const context = createContext({
|
|
414
|
+
dependencyUrls: { auth: 'https://auth.example.com' },
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
expect(resolveEnvVar('API_URL', context)).toBeUndefined();
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('should return undefined when dependencyUrls is not provided', () => {
|
|
421
|
+
const context = createContext();
|
|
422
|
+
|
|
423
|
+
expect(resolveEnvVar('AUTH_URL', context)).toBeUndefined();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('should handle custom domain from config', () => {
|
|
427
|
+
const context = createContext({
|
|
428
|
+
dependencyUrls: { auth: 'https://login.myapp.com' },
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
expect(resolveEnvVar('AUTH_URL', context)).toBe(
|
|
432
|
+
'https://login.myapp.com',
|
|
433
|
+
);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('should prefer user secrets over dependency URLs', () => {
|
|
437
|
+
const context = createContext({
|
|
438
|
+
dependencyUrls: { auth: 'https://auth.example.com' },
|
|
439
|
+
userSecrets: {
|
|
440
|
+
stage: 'production',
|
|
441
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
442
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
443
|
+
custom: { AUTH_URL: 'https://custom-auth.example.com' },
|
|
444
|
+
urls: {},
|
|
445
|
+
services: {},
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// User secrets are checked after dependency URLs, so dependency URL wins
|
|
450
|
+
// If you want user secrets to override, the order in resolveEnvVar should change
|
|
451
|
+
expect(resolveEnvVar('AUTH_URL', context)).toBe(
|
|
452
|
+
'https://auth.example.com',
|
|
453
|
+
);
|
|
454
|
+
});
|
|
455
|
+
});
|
|
350
456
|
});
|
|
351
457
|
|
|
352
458
|
describe('resolveEnvVars', () => {
|
|
@@ -490,4 +596,41 @@ describe('validateEnvVars', () => {
|
|
|
490
596
|
expect(result.missing).toEqual([]);
|
|
491
597
|
expect(result.resolved).toEqual({});
|
|
492
598
|
});
|
|
599
|
+
|
|
600
|
+
it('should resolve dependency URLs in validation', () => {
|
|
601
|
+
const context = createContext({
|
|
602
|
+
dependencyUrls: {
|
|
603
|
+
auth: 'https://auth.example.com',
|
|
604
|
+
api: 'https://api.example.com',
|
|
605
|
+
},
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
const result = validateEnvVars(['PORT', 'AUTH_URL', 'API_URL'], context);
|
|
609
|
+
|
|
610
|
+
expect(result.valid).toBe(true);
|
|
611
|
+
expect(result.missing).toEqual([]);
|
|
612
|
+
expect(result.resolved).toEqual({
|
|
613
|
+
PORT: '3000',
|
|
614
|
+
AUTH_URL: 'https://auth.example.com',
|
|
615
|
+
API_URL: 'https://api.example.com',
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
it('should report missing dependency URLs', () => {
|
|
620
|
+
const context = createContext({
|
|
621
|
+
dependencyUrls: { auth: 'https://auth.example.com' },
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
const result = validateEnvVars(
|
|
625
|
+
['PORT', 'AUTH_URL', 'PAYMENTS_URL'],
|
|
626
|
+
context,
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
expect(result.valid).toBe(false);
|
|
630
|
+
expect(result.missing).toEqual(['PAYMENTS_URL']);
|
|
631
|
+
expect(result.resolved).toEqual({
|
|
632
|
+
PORT: '3000',
|
|
633
|
+
AUTH_URL: 'https://auth.example.com',
|
|
634
|
+
});
|
|
635
|
+
});
|
|
493
636
|
});
|